一.代码块
1.局部代码块
书写位置:方法中
作用:限制作用域
2.构造代码块
书写位置:类中方法外
代码的执行顺序:
1️⃣.系统调用的
2️⃣.只要创建对象就会调用
3️⃣.构造代码块在构造方法之前被调用
3.静态代码块
使用关键词 static修饰的代码块
位置:类中方法外
调用顺序:
1️⃣.随着类的加载而加载
2️⃣.只加载一次
3️⃣.在构造代码块之前执行
应用场景:加载驱动(加载数据库驱动--一个类)
4.同步代码块(多线程)--暂时不做介绍
private static void fun1() { { int num = 10; System.out.println(num); }//局部代码块 可以限制变量的作用域 }
小黄鸭调试法:(逻辑调试)
public static void main(String[] args) { Person p1 = new Person(); p1.name = "Sakura"; p1.sayHi(); Person p2 = new Person("Naruto",18); p2.sayHi(); } class Person{ String name; int age; //无参和有参的构造方法 public Person() { name = "Naruto"; age = 18; System.out.println("我是无参的构造方法"); } public Person(String name,int age) { this.name = name; this.age = age; System.out.println("我是有参的构造方法"); } //介绍自己的方法 public void sayHi() { System.out.println(name + ".." + age + "hahahahaha"); } //吃 public void eat() { System.out.println("吃东西"); } //构造代码块 { System.out.println("我是 构造代码块"); } //静态代码块 static { System.out.println(" 我是静态代码块"); } }
看一下执行后的结果,思考一下执行的顺序:
example:
public class Demo{ static { System.out.println("我是main方法的静态代码块"); } public static void main(String[] args) { System.out.println("我是main 函数"); Test test1 = new Test(); Test test2 = new Test("Naruto"); } } class Test{ String name; public Test(){ System.out.println("我是Test类 无参构造方法"); } public Test(String name){ System.out.println("我是Test类 有参构造方法"); } { System.out.println("我是Test类 构造代码块"); } static { System.out.println("我是Test类 静态代码块"); } }
打印结果:
二.继承
回顾一下面向对象的特征:
封装 继承 多态
继承:
1.可以进行传递
2.继承的是属性和行为(不是全部)
子类可以继承父类的所有成员变量和成员方法,但不能继承父类的构造方法
3.继承 建立类和类之间的关系
继承的好处:
1.减少代码量(提高代码的复用性)
2.提高工作效率
3.增强了 类与类之间的关系(让类和类之间的关系更加紧密)
继承的弊端:
(提)高内聚:希望一个类中 方法与方法之间的联系加强
(降)低耦合:希望类与类之间 减少联系
以上只是代表一种思想 并不是绝对的实现
什么时候使用继承?
继承 一定要符合逻辑 把相同的代码抽成一个类 再使用继承
关键字:extends 父类名字
example:猫狗之于动物
把共有的属性如:名字 毛色 抽成一个父类
class Animal{ String name; String color; public void sayHi() { System.out.println(name + "..." + color); } } class Cat extends Animal{ public void speak() { System.out.println("喵喵喵"); } } class Dog extends Animal{ public void speak() { System.out.println("汪汪汪"); }
java中只允许单继承(通过接口实现多继承)
java中允许多层继承(继承链) A-->B-->C
当你想只使用功能有方法和属性时 使用哪个类的对象?
一般选择使用继承链 最顶端的类
当你想使用特有方法的时候 使用哪个类的对象?
一般选择使用继承链 最末端的类
如果一个类没有写继承 那么这个类默认继承Object类(基类)
public static void main(String[] args) { DemoA a = new DemoA(); Object //当直接打印对象的时候 //相当于调用了 Object类中的 toString方法 System.out.println(a); }
打印出来的是:
全类名@16进制的hashcode码
三.继承中的构造方法
注意:构造方法是不能被继承的
当创建子类对象的时候,为了保证继承的完整性
(不管在创建子类对象的时候 使用的是无参还是有参构造)
系统会默认帮你调用 父类中的无参构造方法
example:
public class Demo{ public static void main(String[] args) { //Father father = new Father(); Son son = new Son(); System.out.println("-----------------"); Son son1 = new Son("儿子"); } } class Father{ String name; public Father() { System.out.println("我是儿子他爸爸的无参构造方法"); } public Father(String name) { this.name = name; System.out.println("我是昂他爸爸的有参构造方法"); } public void sayHi() { System.out.println(name); } } class Son extends Father{ String name; public Son(){ //系统帮你在构造方法的 第一行 写了一句代码 //如果不写 系统会默认帮你加上 super();//调用了父类的构造方法 System.out.println("我是儿子的无参构造方法"); } public Son(String name){ super();//调用父类的构造方法 this.name = name; System.out.println("我是儿子的有参构造方法"); } }
系统会在构造方法的 第一行 写一句代码:super();
如果不写 系统会默认帮你加上
打印结果:
四.super和this
super在子类中代表的是父类的对象
this在子类中可以调用子类的属性和方法
(当子类中没有这个属性 和方法的时候 去父类找 找到就用 找不到就报错)
class TestA{ int num1 = 10; int num2 = 20; public void fun() { System.out.println("我是父类的方法"); } } class TestB extends TestA{ int num2 = 30; public void print() { System.out.println(this.num1); System.out.println(this.num2);//就近原则 //直接调用父类的属性 使用super关键词 System.out.println(super.num2); //也可以调父类的方法 super.fun(); } }
可以在子类中构造方法的第一行 调用一下父类的构造方法(有参 无参都可以)
class Car{ String name; //无参构造方法 public Car() { System.out.println("我是Car的无参"); } //有参构造方法 public Car(String name) { this.name = name; System.out.println("我是Car的有参"); } } class Audi extends Car{ //只要你在构造方法的第一行 //调用一下父类构造方法(无参 有参都行) public Audi() { super("双钻"); System.out.println("我是奥迪的无参"); } public Audi(String name) { super("三钻"); this.name = name; System.out.println("我是奥迪的有参"); } }
五.方法重载和方法重写
方法重载:(Overload)(在一个类中进行)
方法重写:(Override)(前提:至少两个类 并且还要有继承关系)
跟父类的方法完全一致
作用:对父类的该方法进行升级
example:
class IOS7{ public void siri() { System.out.print("说英文"); } } class IOS8 extends IOS7{ String name; //注解:表示这个方法是重写父类 @Override public void siri() { super.siri(); System.out.print("说中文"); } //这个方法一般用来 输出本类中的属性 @Override public String toString() { //调用的是父类方法 //打印出来是全类名@16进制的hashcode码 return "name = "+name; } }
重写父类的方法时 调不调父类的方法要根据你的需求而定
直接打印对象 希望是直接把类的属性输出出来
写一个类都写什么方法?
无参 有参 构造方法
set/get方法
重写toString方法输出属性
private修饰的属性会被子类继承 但是子类无法直接访问
可以间接访问 通过set/get方法来间接访问
六.关键字final
final:
1.修饰方法 方法不能被重写
2.修饰类 类不能被继承
3.修饰变量 变量不能被修改
final修饰引用数据类型不能进行重新指向(地址不能修改)
对象中的属性不会影响修改
一般使用final的时候 会直接定义成静态常量
使用类名直接调用 方便
常量的命名规范 所有字母大写 多单词用下划线分开
ex:
public static final int MAX_VALUE = 10;
堆内存分配的默认值 是无效的默认值
final修饰成员变量的时候 需要赋初始值
赋初始值 有三种方式:
1.声明常量
2.在构造方法中进行赋值
3.在构造代码块中进行赋值