继承
继承可以让子类拥有父类的所有非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{ //无法重写 }
|
如果发现错误请留言告知,万分感谢。
参考资料