1、继承
继承是面向对象三大特征之一(继承、封装、多态),也是实现软件复用的重要手段。
继承就是子类继承父类的(非私有)特征和行为,使得子类对象(实例)具有父类的实例域(实例变量)和方法,或子类从父类继承方法,使得子类具有父类相同的行为,并且可以拥有自己的属性和方法,以此来对父类进行扩展。
- 注:子类使用从父类继承过来的方法的时候,优先使用父类属性(除非子类将父类相同属性进行覆盖时,子类调用重写后的方法,才会使用自己覆盖后的属性,子类从没真正拥有过父类的属性,覆盖以后才算拥有)。
2、继承的特性
- 子类是对父类的扩展,子类是一种特殊的父类。
- Java类只能有一个直接父类,实际上可以有无限多的间接父类(桃子-->水果-->食物-->物品)。
- 子类拥有父类非私有的属性、方法,也可以拥有自己的属性和方法(子类扩展了父类)。
- 子类可以重写父类的方法。
注:重写的要求简记为"两同两小一大":
两同:方法名、形参列表同;
两小:子类方法返回值要比父类的更小或者相等,子类方法声明抛出异常应比父类抛出的异常更小或者相等;
一大:子类方法访问权限应比父类方法访问权限更大或相等。
3、extends和implements
- extends:Java中把extends作为继承的关键字(本意是扩展,子类是对父类的扩展),类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。但是接口可以多继承(
interface C extends A, B {}
)。- implements:implements关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔,
class A implements B,C,D,E,F,G
)。
4、super和this
- super:通过super关键字来实现对父类成员的访问,用来引用当前对象的父类(在子类方法中调用父类被覆盖的方法)。
子类不继承父类的构造器,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。
super.
:代表当前对象的父类对象。
super()
:代表当前对象的父类无参构造器。- this:根据出现位置的不同,有两种情况。
(1)在构造器中引用该构造器正在初始化的对象。
(2)在方法中引用调用该方法的对象。
this.
:代表当前对象。
this()
:代表当前对象的无参构造器。super()
和this()
不能同时出现在同一个构造器中。super()
和this()
必须出现在构造器的第一行。
5、构造器
构造器最大的用处就是在创建对象时执行初始化,当创建一个对象时,系统会为这个对象的实例进行默认的初始化(默认基本类型的数值变量设为0,布尔类型设为false,引用类型设为null)。如果想改变这种默认的初始化,就可以通过自定义构造器来实现(重载)。
修饰符 构造器名(形参列表){构造器执行体}
- 修饰符:可以省略,也可以是public、protected、private之一;
- 构造器名:构造器名必须与类名相同;
- 形参列表:和定义方法形参列表的格式完全相同。
- 作用:
用来配合创建new类的对象的。
代码主要用来实现对象的属性初始化。- 所有类都必须提供构造器,如果类中没有主动声明构造器,则系统自动默认提供一个无参无内容的构造器。
- 构造器既不能定义返回值类型,也不能使用void声明构造器没有返回值!,加了返回值虽然不报错但是,它就是普通方法了,不是构造方法。实际上,构造器是有返回值的,只不过是隐式的,它会返回调用它这个类的实例(其实是一个指向这个实例的堆地址),不写返回值就可以区分正常方法和构造器了。
考:
class A{ public A(int a){ } } class B extends A{ public B(){ //这行报错了,相当于下面一行自动补了一个super(),但是父类只有有参构造器,所以报错了。 } }
举一个栗子:
鸟类有品种、重量、简介三个属性和一个fly方法,其中简介设成私有类型的了,鸵鸟继承了鸟类,它就获得了品种和重量属性,fly方法。其中简介是私有类型的属性,所以它不能继承过来,又因为它不会飞,又对fly方法进行了重写。
Bird .class
public class Bird {
String variety; //品种,包访问权限
float weight;
private String introduction; //鸟类的简介,子类没必要继承所以设成私有的
//构造方法(构造器)
public Bird(String variety, float weight) {
super();
this.variety = variety;
this.weight = weight;
} //重量
public void fly() {
System.out.println("我可以在天上飞!");
}
}
Ostrich.class
public class Ostrich extends Bird{
//新增加了父类没有的属性,扩展了父类,并且设成了私有类型,通过get、set方法操作他们
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//子类自己的构造方法,里面调用了父类的含参构造器
public Ostrich(String variety, float weight, String name) {
super(variety, weight); //通过super显式调用父类含参构造器(配以合适参数)
this.name = name;
}
@Override //因为鸵鸟不会飞,重写了fly方法
public void fly() {
System.out.println("我叫"+this.name+",我是一只"+this.variety+",俺不会飞,只能跑!");
super.fly(); //使用super关键字调用父类被覆盖的fly方法。
}
public static void main(String[] args) {
Ostrich o = new Ostrich("鸵鸟", 5.0f, "小花"); //这时候就调用了构造器,返回了一个对象地址给o
o.fly();
// o.introduction="啦啦啦"; 子类没有继承父类私有属性,所以不能使用introduction
}
}
image.png
网友评论