继承的概念

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。Java中类只支持单继承,Java中可以多层(重)继承(继承体系),java.lang.Object类是所有类的父类。

生活中的继承:

java的继承有几种 java的继承方式_父类

兔子和羊属于食草动物类,狮子和豹属于食肉动物类。

食草动物和食肉动物又是属于动物类。

所以继承需要符合的关系是:is-a,父类更通用,子类更具体。

虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。

类的继承格式

class 父类 { } class 子类 extends 父类 { }

继承的注意事项

  • 子类只能继承父类所有非私有的成员(成员方法和成员变量)
  • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
  • 不要为了部分功能而去继承
  • super关键字
    1.在Java类中使用super来引用父类的(属性、方法和构造器) 2.super可用于访问父类中定义的属性 3.super可用于调用父类中定义的成员方法 4.super可用于在子类构造器中调用父类的构造器
  • 调用父类构造器
    1.在子类的构造器中一定要调用一次父类的构造器,系统默认调用的是父类无参数的构造器。2.如果子类构造器中既未显式调用父类构造器,而父类中又没有无参的构造器,则编译出错 3. 如果父类没有无参数的构造器,在子类的构造器中可使用语句super()调用父类相应有参数的构造器
  • java的继承有几种 java的继承方式_子类_02

常见面试题1:

class Test02_Extends {
    public static void main(String[] args) {
        Zi z = new Zi();
    }
    /*
    1,jvm调用了main方法,main进栈
    2,遇到Zi z = new Zi();会先将Fu.class和Zi.class分别加载进内存,再创建对象,当Fu.class加载进内存
    父类的静态代码块会随着Fu.class一起加载,当Zi.class加载进内存,子类的静态代码块会随着Zi.class一起加载
    第一个输出,静态代码块Fu,第二个输出静态代码块Zi
    3,走Zi类的构造方法,因为java中是分层初始化的,先初始化父类,再初始化子类,所以先走的父类构造,但是在执行
    父类构造时,发现父类有构造代码块,构造代码块是优先于构造方法执行的所以
    第三个输出构造代码块Fu,第四个输出构造方法Fu
    4,Fu类初始化结束,子类初始化,第五个输出的是构造代码块Zi,构造方法Zi
    */
}
class Fu {
    static {
        System.out.println("静态代码块Fu");
    }

    {
        System.out.println("构造代码块Fu");
    }

    public Fu() {
        System.out.println("构造方法Fu");
    }
}

class Zi extends Fu {
    static {
        System.out.println("静态代码块Zi");
    }

    {
        System.out.println("构造代码块Zi");
    }

    public Zi() {
        System.out.println("构造方法Zi");
    }
}

 

java的继承有几种 java的继承方式_System_03

执行顺序:父类>子类   静态>非静态  

常见面试题2:

java的继承有几种 java的继承方式_System_04

解析:父类的printB和printC都是私有的,子类不能重写,所以就调了父类的方法。
父类中的方法public void printABC()在子类中没有重写,所以在子类对象调用这个方法的时候,实际上是调用的父类里面的printABC()方法,父类里面的printABC()方法又会去调用父类里的三个方法printA(),printB(),printC(),这三个方法除非被覆盖,否则就还是输出父类里面定义的内容。

类的静态变量和静态方法能否被子类继承?                                                                                                                                    结论:java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.

常见面试题3:向上转型

public class day01_1 {
    public static void main(String[] args) {
        Shape sh = new circle();
        System.out.println(sh.name);
        sh.printType();
        sh.printName();
    }
}
class Shape{
    public String name = "shape";
    public Shape(){
        System.out.println("shape constructor");
    }
 
    public void printType() {
        System.out.println("this is shape");
    }
 
    public static void printName() {
        System.out.println("shape");
    }
}
 
class circle extends Shape{
    public String name = "circle";
    public circle(){
        System.out.println("circle constructor");
    }
 
    public void printType() {
        System.out.println("this is circle");
    }
 
    public static void printName(){
        System.out.println("circle");
    }
}

java的继承有几种 java的继承方式_System_05

解析:因为指向子类的引用向上转型变成了shape,所以他只能访问父类的属性和方法。当父类的引用指向子类时,使用对象调用静态方法或者静态变量,是调用的父类中的方法或者变量。注:在Java中,只能重写方法,不会重写成员变量,而是隐藏成员变量。