java系列:继承使用细节

188 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情

使用细节

com.gaogao.extend_包:ExtendsDetail.java

package com.gaogao.extend_;
​
public class ExtendsDetail {
    public static void main(String[] args) {
        Sub sub = new Sub();
//        sub.sayOk();
​
        Sub sub1 = new Sub("name" ,20);
​
​
    }
}
  1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供的公共的方法去访问

  2. 子类没有继承父类的构造器,但必须调用父类构造器,完成父类的初始化。在子类的构造器中,隐藏了一句super();这句话会默认调用父类构造器

  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过(sub.java)

  4. 如果希望指定去调用父类的某个构造器,则显式调用一下 super(形参列表/无参);

  5. super在使用时,需要放在构造器第一行

  6. super()和this()都只能放在构造器第一行,因此这两个方法不能共存一个构造器内

  7. java所有类都是Object类得到子类

  8. 父类构造器的调用不限于直接父类!将一致往上追溯直到Object类(顶级父类 )

  9. 子类最多只能继承一个父类(指直接继承)即java中是单继承机制。思考:如何让A类继承B类和C类?

  10. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系

    Person is a Music?;
    Person Music;
    Music extends Person;
    ​
    Animal;
    Cat extends Animal
    

继承的本质(重点!)

先看一个案例,来分析当子类继承父类,创建子类对象时,内存中到底发生了什么?

提示:当子类对象创建好后,建立查找的关系

com.gaogao.extend_包:ExtendsTheory.java

子类创建的内存布局

image-20221205210746162.png

课堂练习

放在com.gaogao.extend_exercise包下

  1. 案例1ExtendsExercise01.java

    package com.gaogao.extend_;
    ​
    import com.gaogao.modifier.A;
    import com.gaogao.modifier.B;
    ​
    public class ExtendsExercise01 {
        public static void main(String[] args) {
    //        B b = new B();
    ​
        }
    ​
    }
    ​
    //class A{
    //    A(){
    //        System.out.println("a的默认构造器被调用");
    //    }
    //    A(String name){
    //        System.out.println("a name被调用");
    //    }
    //}
    //
    //class B extends A {
    //    B(){
    //        this("abc");
    //        System.out.println("b的默认构造器被调用");
    //    }
    //    B(String name){
    //
    //        System.out.println("b name被调用");
    //    }
    //}
    
  2. 案例2ExtendsExercise02.java

    package com.gaogao.extend_;
    ​
    public class ExtendsExercise02 {
        public static void main(String[] args) {
            C c = new C();
    ​
        }
    }
    class A{
        public A(){
            System.out.println("我是A类的无参构造器");//1
        }
    ​
    }
    ​
    class B extends A{
        public B(){
    ​
            System.out.println("我是B类的无参构造器");
        }
        public B(String name){
    ​
            System.out.println(name + "我是B类的有参构造器");//2
        }
    }
    ​
    class C extends B{
        public C(){
            this("Hello");
            System.out.println("我是C类的无参构造器");//4
        }
        public C(String name){
            super("haha");
            System.out.println("我是C类的有参构造器");//3
        }
    }
    
  3. 案例3ExtendsExercise03.java

    package com.gaogao.extend_;
    ​
    public class ExtendsExercise03 {
        public static void main(String[] args) {
    ​
            PC pc = new PC("英特尔", 2, 512);
            pc.setBrand("戴尔");
            System.out.println("电脑的配置为 " + pc.getDetails() + pc.getBrand());
            NotePad notePad = new NotePad("AMD", 4, 1024);
            notePad.setColor("黑色");
            System.out.println("notepad的配置为 " + pc.getDetails() + notePad.getColor());
    ​
    ​
        }
    }
    

案例3:ExtendsExercise03.java

编写Computer类,包含CPU,内存,硬盘等属性,getDetails方法用于返回Computer的详细信息

编写PC子类,继承Computer类,添加特有属性品牌【品牌brand】

编写NotePad子类,继承Computer类,添加特有属性【颜色color】

编写Test类,在main方法中创建PC和NotePad对象,分别给对象中的特有属性赋值,以及从Computer类继承的属性赋值,并使用方法并打印输出信息