类和对象进阶 - 继承

1. 继承

1.1 继承解决了什么问题 ? java中如何实现继承 ?

对类的共性进行抽取 对代码进行复用     java中, 使用extends关键字 关联
 
查看代码
/*
class Dog {
    public String name;
    public int age;
    public float weight;

    public void eat() {
        System.out.println(name + "正在吃饭");
    }

    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

class Cat {

    public String name;
    public int age;

    public void eat() {
        System.out.println(name + "正在吃饭");
    }

    public void sleep() {
        System.out.println(name + "喵叫");
    }
}*/

// 发现上述代码 有很多重复的地方
// 继承用来 复用代码
//
class Animal {
    public String name;
    public int age;

    public void eat() {
        System.out.println(name + "正在吃饭");
    }
}

class Dog extends Animal{
    public String color;

    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

class Cat extends Animal{
    public void sleep() {
        System.out.println(name + "喵叫");
    }

}

public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "小白";
        System.out.println(cat.name);

        Dog dog = new Dog();
        dog.name = "大黄";
        System.out.println(dog.name);
    }
}
 

1.2 子类继承父类什么 ?  子类对象如何存储 ?

子类继承父类的成员变量和方法,除了父类构造方法和父类中的静态成员

查看代码
 class Animal {
    public String name;
    public int age;
    public static int id = 1;

    public void eat() {
        System.out.println(name + "正在吃饭");
    }
}

class Dog extends Animal{
    public String color;

    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}



public class Main {
    public static void main(String[] args) {

        Dog dog = new Dog();
        dog.name = "a";
        dog.age = 2;
    }
}

分为两块 一部分存储父类的 一部分存储子类自己的

 

 

1.3 访问优先级

子类与父类存在同名成员时,优先访问子类自己的成员变量/方法如果访问的成员方法子类中无,则访问父类继承下来的如果父类也没有定义,则编译报错

查看代码
 class Base {
    public int a = 1;
    public int b = 2;

    public void test() {
        System.out.println("Base::test()");
    }

}

class Derived extends Base {
    public int a = 10;
    public int c = 3;

    public void test() {
        System.out.println("Derived::test()");
    }
    public void test2() {
        System.out.println("Derived::test2()");
    }

    public void test(int a) {
        System.out.println(a);
    }

    public static void main(String[] args) {
        Derived derived = new Derived();

        // 存在同名成员时,优先访问子类自己的成员变量 / 方法
        // 访问的成员方法子类中无,则访问父类继承下来的
        // 如果父类也没有定义,则编译报错
        System.out.println(derived.a);
        derived.test();
        derived.test2();
    }


}

 

1.4 super关键字

super 表示父类数据对象的引用, 用来指定访问 父类成员
 
this 表示对象的引用

 

查看代码
class Base {
    public int a = 1;
    public int b = 2;

    public void test() {
        System.out.println("Base::test()");
    }
}

class Derived extends Base {
    public int a = 10;
    public int c = 3;

    public void test() {
        System.out.println("Derived::test()");
    }
    public void test2() {
        System.out.println("Derived::test2()");
    }

    public void test(int a) {
        System.out.println(a);
    }

    public void method() {
        // super this
        System.out.println(this.a);
        System.out.println(super.a);
    }

    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.method();
    }
}

super关键字总结与注意事项

总结:

1. super用来在子类中 指定访问父类成员变量和方法 因为this引用优先访问子类自己的成员

2. super加点号 访问父类成员变量和方法

3. super(..) 访问父类的构造方法

注意事项:

1. super只能在非静态方法中使用

2. 在子类构造方法中调用super(...)初始化父类成员,必须放在第一行

 

super与this 相同点和不同点

相同点:

1. 都是Java中的关键字

2. 只能在类的非静态方法中使用

3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

不同点:

1. this是当前对象的引用  —— super 是从父类继承下的部分成员变量的引用 如图

2.  在非静态成员方法中,this优先访问子类自己的成员变量和属性 如果找不到子类成员 再去访问父类成员 —— super 指定访问父类的成员

3. 在子类构造方法中,this(...)用于调用子类自己的构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现 因为this() super()都需要占用第一行

4.  子类构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)调用用户不写则没有

 

1.5 子类对象如何初始化 ?

首先调用父类构造方法给子类对象中的父类成员进行初始化
 
然后再初始化子类自己的成员
class Animal {
    public String name;
    public int age;

    public void eat() {
        System.out.println(name + "正在吃饭");
    }

    public Animal(String name,int age) {
        this.name = name;
        this.age = age;
    }
}

class Dog extends Animal{
    public String color;

    public Dog(String name,int age) {
        // 在子类自己成员变量初始化前 必须先调用父类构造初始化子类对象中的父类成员
        super(name,age);
        this.color = "黑色";
    }

    public static void main(String[] args) {
        Dog dog = new Dog("a",1);
        System.out.println(dog.name);
    }
}

 

为什么自己没写构造,编译器不报错 ?
class Animal {
    public String name;
    public int age;

    public void eat() {
        System.out.println(name + "正在吃饭");
    }
    
    // 默认生成 Animal构造
    /*public Animal() {
        
    }*/
}

class Dog extends Animal{
    public String color;

    // 默认生成 Dog构造
    /*public Dog() {
        自动生成 super()
        super();
    }*/
    

    public static void main(String[] args) {
       Dog dog = new Dog();
    }
}

 

1.6 继承关系上的执行顺序

父类的静态,子类的静态,父类的实例,父类的构造,子类的实例,子类的构造
class Animal {
    public String name;
    public int age;

    public Animal() {
        System.out.println("Animal()");
    }

    static {
        System.out.println("Animal::static{}");
    }

    {
        System.out.println("Animal::{  }");
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Animal(String name, int age)");
    }

    public void eat() {
        System.out.println(this.name+"正在吃.....");
    }
}

class Dog extends Animal {

    public String color;

     public Dog() {
         //super();
         System.out.println("Dog()");
     }

    static {
        System.out.println("Dog::static{}");
    }

    {
        System.out.println("Dog::{  }");
    }

    public static void main(String[] args) {
        Dog dog = new Dog();
    }

}

 

1.7 java继承关系与final修饰类

 

 

2. 访问修饰限定符

class Person implements Cloneable {
    public String name;
    public int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException{
        // 一定得在子类方法中, 调用protected修饰的父类成员
        return super.clone();
    }
}

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("a",1);
        Person p2 = (Person) person1.clone();
        System.out.println(p2.name);
    }
}

 

posted @ 2023-11-09 21:21  qyx1  阅读(47)  评论(0)    收藏  举报  来源