Java-8 继承与super关键字

一、引入

1、语法

A extends B

A:子类/派生类

B:父类/基类/超类

2、作用:

对多个类的共性进行提取,达到代码的复用 

如:Cat类和Dog类,都需要有名字属性,吃饭方法,就可以写一个Animal类,代码如下

写一个Animal类

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

写一个Cat类

class Cat extends Animal{//继承Animal的属性和方法
    public void mew(){
        System.out.println(this.name+"喵喵喵");//可以写自己的方法
    }
}

写一个Dog类

class Dog extends Animal{//继承Animal的属性和方法
    public void bark(){
        System.out.println(this.name+"汪汪汪");//写自己的方法
    }
}

二、子类继承了父类的成员属性/方法

1、访问方式

已经变成了子类自己的成员属性/方法,和子类访问自己的成员属性/方法一样,可以直接在方法中访问,也可以通过对象名.属性/对象名.方法来访问

2、代码演示

class A{
    int a;
    int b;
    public void func1(){
        System.out.println("父类的方法");
    }
}
class B extends A{
    int c;
    {
        a = 100; //访问继承的属性a
        c =200;//访问自己的变量
    }


}
public class TestDemo {
    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.a);//访问继承的属性a
        b.func1();//访问继承下来的func1方法
    }
}

 三、当子类与父类的成员属性/方法名相同

1、访问顺序

当出现子类与父类的成员属性/方法名相同时,优先访问自己的,称为就近原则。

2、代码演示

class A{
    int a = 100;
    public void func(){
        System.out.println("父类的方法");
    }
}
class B extends A{
    int c;
    int a = 200; //与父类同名的属性a
    public void func(){ //与父类同名的方法func()
        System.out.println("子类的方法");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.a);//访问同名的属性
        b.func();//访问同名的方法
    }
}

结果调用子类的a和子类的func()方法 

 四、super关键字

1、作用

当子类成员属性/方法名相同时,默认调用子类自己的,如果我们想调用父类的,就需要用到super关键字。

2、语法

super.data //调用父类的属性

super.func() //调用父类的方法

super() //调用父类的构造方法

3、代码演示 

class A{
    int a =100;
    public void func(){
        System.out.println("父类的方法");
    }
}
class B extends A{
    int c;
    int a =200; //与父类同名的属性a
    public void func(){ //与父类同名的方法func()
        System.out.println("子类的方法");
    }
    public void method(){
        System.out.println(super.a);//调用父类的成员属性
        super.func(); //调用父类的成员方法
    }
}
public class TestDemo {
    public static void main(String[] args) {
        B b = new B();
        b.method();
    }
}

 4、注意

1、super关键字和this关键字一样,只能在非静态的方法中使用

2、super用来访问父类继承下来的方法和属性

3、this是非静态成员方法的一个隐藏参数,super不是隐藏的参数

 五、构造方法

1、当父类写了一个无参数的构造方法

子类会默认生成一个构造方法

public 子类名 {
           super();

}

class Animal{
    String name;
    public void eat(){
        System.out.println(this.name+"正在吃饭");
    }
    public Animal(){
        System.out.println("父类的构造方法");
    }
}
class Cat extends Animal{
    public void mew(){
        System.out.println(this.name+"喵喵喵");
    }
//    public Cat(){ //默认生成的
//        super(); //调用父类的构造方法
//    }
}
public class TestDemo {
    public static void main(String[] args) {
        Cat cat = new Cat(); //当实例化对象的时候,就会调用Cat类的构造方法
    }

}

2、父类写了一个有参数的构造方法

 当构造子类的时候,子类需要先帮父类构造,才能使得代码正常运行

解决办法: 

写一个构造方法,在第一行调用父类的构造方法,注意super()一定要在第一行

class Cat extends Animal{
    public Cat(){   
        super("咪咪"); //显示调用父类的构造方法,来初始化子类从父类继承过来的东西
    }
}

 

 六、再谈初始化

1、执行顺序

在之前讲过的代码块中,执行顺序是静态代码块 > 实例代码块 > 构造代码块

在继承关系中,执行顺序依然是静态代码块 > 实例代码块 > 构造代码块,但父类总是优先于子类

2、代码演示

class Person{
    {
        System.out.println("Person:实例代码块");
    }
    static {
        System.out.println("Person:静态代码块");
    }
    public Person(){
        System.out.println("Person:构造代码块");
    }
}
class Student extends Person{
    {
        System.out.println("Student:实例代码块");
    }
    static {
        System.out.println("Student:静态代码块");
    }
    public Student(){
        System.out.println("Student:构造代码块");
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student();
        Student student2 = new Student();
    }
}

猜你喜欢

转载自blog.csdn.net/benxiangsj/article/details/129540432