目录
什么是继承?
通俗来讲,在Java中,如果一个或多个类实例化出的对象之间都存在共有的属性,那么就可以在一另一个类中去定义这些属性,之后每个对象需要用到这些属性时可以直接用,最终可以实现共性的抽取,代码的复用。
举个栗子:马和狗都是动物,都具有名字、年龄、吃饭、睡觉等共有属性,那么就可以将这些属性归纳在一起放入一个类当中,这个类就叫做父类(或基类、超类),而马或狗的类就叫做子类(或派生类)。
通过下面这段代码,我们先简单感受一下继承写法:
class Animals{
public String name;
public int age;
public void eat(){
System.out.println("正在吃饭");
}
}
class Horse extends Animals{
public boolean Strong;
public void run(){
System.out.println("日行千里");
}
}
class Dog extends Animals{
public boolean silly;
public void houseGuard(){
System.out.println("看家护院");
}
}
继承的访问特性
子类通过对象访问父类成员:
1.访问成员变量
- 如果访问的成员变量子类中有,则访问子类自己的;
- 如果访问的成员变量子类中没有,则访问从父类中继承下来的,如果父类中也没有,则编译错误;
- 如果子类中存在与父类同名的成员变量,优先访问子类自己的。如果非要访问父类的变量,则需要借助关键字super.变量名引用;
- 如果要访问的父类中私有的成员变量,可以借助Generate中的Getter方法;
2.访问成员方法
- 如果要访问子类和父类中不同名的方法,先在子类中找,找得到则访问子类的,找不到再去父类中找,找到了就访问父类继承下来的,否则编译错误;
- 如果要访问子类和父类中同名的方法,如果是重载关系,会根据传入的参数选择对应的方法。如果完全一样(不是重载关系),会优先访问子类自己的该方法。
- 如果非要访问父类中与子类同名的方法,则也只需要在子类中使用super.方法名即可
当然子类也可以直接在子类内部调用父类成员
子类构造方法
我们知道类要实例化出对象需要传参,而子类的属性定义在父类中,要想给子类对象初始化改怎么做呢?
其实正所谓子类继承父类,那当然就是先有父类才有子类。
1.无参构造方法
这是我们自己不写构造方法时,可以直接给子类成员变量赋值,其实这种情况下,是编译器自动调用了子类和父类各自当中无参的构造方法。
2.有参的构造方法
首先:父类和子类都要有有参数的构造方法;
其次:使用super(参数1,参数二)调用父类的构造方法,要求是这一句必须放在子类构造方法的第一句。
子类也可以借助无参的调用有参的构造方法:
注意:
如果使用super在子类无参的构造方法中,就不能带第三个参数了,因为super是为父类成员初始化(不需要strong),而this是对当前对象初始化(需要strong)。同时要注意这两种写法不能同时出现在无参的构造方法中。
super关键字
在上面我们已经提到了super的使用——调用父类成员。
super在继承中的作用:
- 访问父类中与子类同名的成员变量;
- 访问父类中与子类同名的成员方法;
- 访问不同包的子类中被protected修饰的成员变量;
- 参与子类构造方法中对父类构造方法的调用;
- 只能在非静态方法中使用;
继承方式
分为三种:
在多层继承中, 一般我们不要超过三层;
final关键字
有时候我们需要限制类的继承层数,就可以使用final;
修饰类:表示该类为最终类,无法再被继承;
修饰变量或字段:表示常量(即不能被修改)
修饰方法:表示该方法不能再重写
组合
将一个类的实例作另为一个类的字段;
通俗的讲:将一个事物分成多个部分,每个部分对应一种类,如果将每一种类实例化出来的对象放入另一个类中,就是一个组合。
举个栗子:
class Cpu{
//...cpu类
}
class Graphics{
//...显卡类
}
class Screen{
//...显示器类
}
class Keyboard{
//...输入类
}
class Computer{
//电脑包含了以下这些字段
private Cpu cpu;
private Graphics graphics;
private Screen screen;
private Keyboard keyboard;
}