目录
理解
将相同的属性和方法提出来构成一个方法 然后可以被继承
子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整 ,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。
内容
1、this会优先访问子类自己的,如果子类没有,访问的就是父类的
2、super只是一个关键字,在代码层面上,能够达到易读的效果。只访问父类的
3、此时虽然执行了父类的构造方法,但是并没有生成父类的对象,这里只是帮助子类初始化从父类继承过来的属性。
注意:
- 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构 造方法
- 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的 父类构造方法调用,否则编译失败。
- 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
- super(...)只能在子类构造方法中出现一次,并且不能和this同时出现
代码
- class Animal{
- public String name;
- public int age;
-
- public Animal(String name,int age)//父类构造方法
- {
- this.name = name;
- this.age = age;
- }
-
- public void eat(){
- System.out.println(name+"吃饭");
- }
- }
-
- class Dog1 extends Animal{
- // 傻 是狗1的特殊属性
- public boolean silly;
-
- //有参数要自己显性构造方法
- public Dog1(String name,int age,boolean silly){
- super(name,age);//必须在第一行,先帮父类部分初始化
- this.silly = silly;
- }
- public void houseGuard(){
- System.out.println(super.name+"正在看家护院");
- System.out.println(name+"正在看见护院");
- }
- }
-
- /*class Cat extends Animal{
- // 猫特有的行为
- public void catchMouse(){
- System.out.println(name+"抓老鼠");
- }
- }*/
-
- public class TestAnimal {
- public static void main(String[] args) {
- Dog1 dog = new Dog1("xiao",18,false);
- //Cat cat = new Cat();
-
- }
- }
-
理解
- 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
在构造方法中:super用于调用父类构造方法,不能同时与this在构造方法中出现
构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加
内容
Dog1 dog = new Dog1("xiao",18,false);
带参数的构造需要自己创建构造函数
创建Dog1对象的时候会调用
public Dog1(String name,int age,boolean silly){ super(name,age);//必须在第一行,先帮父类部分初始化 this.silly = silly; }super可以理解成调用
public Animal(String name,int age)//父类构造方法 { this.name = name; this.age = age; }
代码
class Animal{ public String name; public int age; public Animal(String name,int age)//父类构造方法 { this.name = name; this.age = age; } } class Dog1 extends Animal{ // 傻 是狗1的特殊属性 public boolean silly; //有参数要自己显性构造方法 public Dog1(String name,int age,boolean silly){ super(name,age);//必须在第一行,先帮父类部分初始化 this.silly = silly; } // 狗的特有行为 public void houseGuard(){ System.out.println(super.name+"正在看家护院"); System.out.println(name+"正在看见护院"); } } public class TestAnimal { public static void main(String[] args) { Dog1 dog = new Dog1("xiao",18,false); } }
理解
静态——实例——构造
内容
结论:
1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
注意:
- 静态代码块先执行,并且只执行一次,在类加载阶段执行
- 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行
代码
class Person { public String name; public int age; public Person(String name, int age) { this.name = name; this.age = age; System.out.println("1:Person:构造方法执行"); } { System.out.println("2:Person:实例代码块执行"); } static { System.out.println("3:Person:静态代码块执行"); } } class Student extends Person{ public Student(String name,int age) { super(name,age); System.out.println("4:Student:构造方法执行"); } { System.out.println("5:Student:实例代码块执行"); } static { System.out.println("6:Student:静态代码块执行"); } } public class TestDemo4 { public static void main(String[] args) { Student student1 = new Student("张三",19); System.out.println("==========================="); Student student2 = new Student("李四",20); //代码输出为:14 2356
理解
可在不同包的子类里调用
内容
注意:父类中private成员变量虽然在子类中不能直接访问,但是也继承到子类中了
代码
- package demo1;//在demo1下的同一类
-
- public class TestDemo {
- protected int a = 10;//a被protected修饰
- public void func(){
- System.out.println(a);
- }
- }
-
- package demo1;//在demo1下的不同类
-
- public class TestDemo2 {
- public static void main(String[] args) {
- TestDemo testDemo = new TestDemo();
- System.out.println(testDemo.a);
- }
- }
-
- package demo2;//在demo2不同包的子类
- import demo1.TestDemo;
- //不同包的子类
- public class Test extends TestDemo {
- public void test(){
- System.out.println(super.a);
- }
-
- public static void main(String[] args) {
- Test t = new Test();
- t.test();
- }
- }
-
理解
继承:可以看做 是 is - a的关系 class Dog extends Animal Dog is a Animal
组合:a part of / has-a 的关系 学生和老师 是学校的一部分 学校有学生和老师
内容
组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合。
代码
// 轮胎类 class Tire{ // ... } // 发动机类 class Engine{ // ... } // 车载系统类 class VehicleSystem{ // ... } class Car{ private Tire tire; // 可以复用轮胎中的属性和方法 private Engine engine; // 可以复用发动机中的属性和方法 private VehicleSystem vs; // 可以复用车载系统中的属性和方法 // ... } // 奔驰是汽车 class Benz extend Car{ // 将汽车中包含的:轮胎、发送机、车载系统全部继承下来 }
理解
final关键可以用来修饰变量、成员方法以及类。
内容
- 修饰变量或字段,表示常量(即不能修改)
修饰类:表示此类不能被继承 String 字符串类, 就是用 final 修饰的, 不能被继承.
修饰方法:表示该方法不能被重写
代码
final int a = 10; a = 20; // 编译出错
final public class Animal { ... } public class Bird extends Animal { ... } // 编译出错Error:(3, 27) java: 无法从最终com.bit.Animal进行继