继承

继承

继承可以让子类拥有父类的所有非private的方法和属性,并且子类可以在父类的基础上添加
自己特有的方法和属性。可以简单的理解为,继承让父类变得更加特殊,可以描述的范围更窄。

我们假设交通工具是一个父类,那么我们可以创建一些子类如:飞机,汽车,轮船。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Vehicle {
private String id;
private String destination;
private int passenger;

public Vehicle(String id, String destination, int passenger)
{
this.id = id;
this.setDestination(destination);
this.setPassenger(passenger);
}

public void way()//如何去目的地
{
System.out.printf("tele-transmit");
}


//----------------------GETTER/SETTER------------------------
public String getDestination() {
return destination;
}

public void setDestination(String destination) {
this.destination = destination;
}

public int getPassenger() {
return passenger;
}

public void setPassenger(int passenger) {
this.passenger = passenger;
}
}

拿子类飞机为例,他肯定是要有父类的所有属性,并且我们可以根据飞机的特运输特性,给 他添加一个新的属性:飞行高度。

1
2
3
4
5
6
7
8
public class Plane extends Vehicle{
private int altitude;

public Plane(String id, String destination, int passenger,int altitude) {
super(id, destination, passenger);
this.altitude = altitude;
}
}
  • extends是继承的关键字。
  • Java 不允许多继承。一个子类只有一个父类,正如每个人只有一个die。
  • super是调用父类属性或方法的关键字。
  • 如果在子类要调用父类构造方法,super()一定要放子类构造方法的第一行。
  • 子类拥有父类所有非private的方法和属性

重定义方法/重写方法

本身Vehicle有如何去到目的地的方法way(),但是飞机应该是飞去目的地而不是传送过去,
所以我们需要在子类重新定义这个方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Plane extends Vehicle{
private int altitude;

public Plane(String id, String destination, int passenger,int altitude) {
super(id, destination, passenger);
this.altitude = altitude;
}

@Override
public void way()
{
System.out.println("id: " + super.getId() + " fly fly fly!");
//或者我们可以飞到一半再传送
//super.way();
}
}
1
2
3
4
5
6
7
8
9
10
public class Test{
public static void main(String[] args) {
Vehicle v = new Vehicle("1","beiking",1);
Plane f = new Plane("2","shanghai",200,20000);

v.way();//id: 1 tele-transmit
f.way();//id: 2 fly fly fly!

}
}
  • @Override是重写的关键字。
  • 重写的方法必须拥有相同的函数名,返回值,对应的参数类型和个数。
  • 重写和重载@Overload不同,重载是给类多加了一个新方法,因为方法的参数数量和类型不同,而重写是同一个方法内容不同。

构造方法及调用顺序

如果子类没有自己的构造方法,那么他会调用父类的构造方法。因为默认调用父类的无参构造方法。

1
2
3
4
5
6
7
public class Plane extends Vehicle{

//如果没有构造方法,系统添加如下构造方法
public Plane() {
super();
}
}

所以当我们新建一个子类plane,他会首先调用Plane的构造方法,然后因为Plane()的第一行是super(),所以会调用对应的父类Vehicle的构造方法。
而执行顺行是先执行Vehicle的构造方法,再执行Plane的构造方法。原理如同递归函数的调用与执行。

### 超类 Object Object是所有类的父类(所以称其为超类)。原因在于所有没有extends关键字的类(如Vehicle),都默认继承了Object类。所以即使子类(Plane)没有直接继承Object类,但是间接继承了Object类的属性和方法。Object类主要方法如下:
  • public String toString()以字符串的形式返回对象信息。
  • public boolean equals(Object obj)如果不重写此方法,那么系统会拿两个对象的地址进行比较。
  • public int hashCode() 如果重写了equals()方法,此方法也要重写,以免在用hash表的时候出现hashcode相同而出现问题(后面会有文章解释,为什么不用重写hashCode(),hash表也不会出问题)。

final

final修饰的方法不能被重写。

1
2
3
4
5
6
7
8
9
10
11
12
public class Vehicle {

public final void way()//如何去目的地
{
System.out.printf("tele-transmit");
}
}

public class Plane extends Vehicle{
//无法重写
}

如果发现错误请留言告知,万分感谢。

参考资料


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!