继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
举个例子:
class Animal {
private int age;
private String name;
public void speak() {
System.out.println("Animal在说话");
}
}
class Dog extends Animal {
private String color;
public void eat() {
System.out.println("Dog在吃饭");
}
}
这是一个简单的关于继承的例子
- Dog类中的也有speak()方法,这是继承自Animal类
- Dog类中也有age,name属性,同样继承自Animal类
- Dog类中的color属性和eat()方法是新增加的
在通过扩展超类定义子类的时候,仅需要指出子类与超类的不同之处。因此在设计类的时候,应该将通用的方法放到超类中,而将具有特色用途的方法放在子类中,这种将通用的功能放到超类的做法,在面向对象程序设计中十分普遍。
关键字:extends
class Manager extends Employee {}
其中 Manager是子类,Employee是父类。
这是一个稍微复杂的例子:
public class Employee {
private String name;
private double salary;
private Date hireDay;
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month, day);
hireDay = calendar.getTime();
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
//more method
......
}
public class Manager extends Employee{
...
private double bonus;
public void setBonus(double bonus,String n, double s, int year, int month, int day) {
super(String n, double s, int year, int month, int day);
this.bonus = bonus;
}
@Override
public double getSalary() {
return super.getSalary() + bonus;
}
}
}
Manager类中的getSalary方法显然和Employee类不同,因为他还包含了bonus属性,因此可以重写(Override)此方法,让它满足Manager类的要求,此时就会覆盖父类的同名方法。
@Override
public double getSalary() {
return salary + bonus;//don't work
}
虽然Manager类继承Employee类的salary字段,但是却无法在Manager类中直接访问其父类的私有字段。
因此应该使用关键字super,调用父类的getSalary()方法
@Override
public double getSalary() {
return super.getSalary() + bonus;
}
super 关键字有两个用途:
一、 调用超类的方法,
二、 是调用超类的构造器。
super 不是一个对象的引用,不能将 super 赋给另一个对象变量,它只是一个指示编译器调用超类方法的特有关键字。
由于 Manager 类的构造器不能访问 Employee 类的私有域,所以必须利用 Employee 类的构造器对这部分私有域进行初始化,我们可以通过 super 实现对超类构造器的调用。使用 super 调用构造器的语句必须是子类构造器的第一条语句。
public void setBonus(double bonus,String n, double s, int year, int month, int day) {
super(String n, double s, int year, int month, int day);
this.bonus = bonus;
}
先举个例子:
class Animal {
private static String A = Animal.fun1("Animal's static A is init");
public Animal() {
super();
System.out.println("--Animal--");
}
public static String fun1(String s) {
System.out.println(s);
}
}
class Dog extends Animal{
private static String D = Animal.fun1("Dog's static D is init");
public Dog() {
super();
System.out.println("--Dog--");
}
}
class Hasky extends Dog{
private static String H = Animal.fun1("Hasky's static H is init");
public Hasky() {
super();
System.out.println("--Hasky--");
}
}
public class Test {
public static void main(String[] args) {
Hasky h = new Hasky();
}
}
运行结果:
Animal's static A is init
Dog's static D is init
Hasky's static H is init
--Animal--
--Dog--
--Hasky--
当创建子类对象时,会生成一个构造函数链Hasky–>Dog–>Animal–>Object,最后再执行Hasky的构造函数。这种向上链接的方式是有意义的。因为父类的字段在大多数情况下都是private的,子类没有权限对这些private字段初始化,因此只能让父类自己完成初始化,以确保父类的状态是完整的。
从运行结果可以看出:
public static void main(String[] args) {
Hasky h = new Hasky();
}
首先main()方法执行,加载Test类,然后创建Hasky对象,此时加载Hasky类。
class Hasky extends Dog{}
但是此时jvm又看到extends关键字,Hasky继承自Dog,所以开始加载Dog类。
class Dog extends Animal{}
同理开始加载Animal类。
而在类加载后,静态字段,方法都会被加载,因此private static String A,private static String D,private static String H被依次加载。
2. 然后完成构造函数链。
注意
如果将Animal,Dog,Hasky的实例字段不声明为static
class Animal {
private String A = Animal.fun1("Animal's A is init");
}
class Dog {
private String D = Animal.fun1("Dog's D is init");
}
class Hasky {
private String H = Animal.fun1("Hasky's H is init");
}
运行结果:
Animal's A is init
--Animal--
Dog's D is init
--Dog--
Hasky's H is init
--Hasky--
类初始化的过程
Aniaml animal = new Dog();//Dog is a Animal
Dog d = new Aniaml();//don't work,Animal is not a Dog
子类可以比父类有更多的字段和方法,但最少要包括父类的全部字段和方法。
继承只有单继承,要实现多继承就只能借助接口(实现)
在面向对象语言中,继承是必不可少的、非常优秀的语言机制,它有如下优点:
自然界的所有事物都是优点和缺点并存的,继承的缺点如下:
在创建子类对象时,实际上在其内部维护了一个父类对象。但是并没有new一个父类对象,而只是调用了父类的构造方法,确保了父类的状态。
是将name字段和hiredate字段放在Employee中,而没有将它重复放在Manager中
第一,子类集合无限制,任何一个人都可以从一个类继承,然后编写代码直接访问protect字段,从而破坏了封装性。
第二,Java中同一个包中的所有类都可以直接访问protect字段,而不管它们是否为这个类的子类。
要保证子类 “is a” 父类的关系,这样此时比较好的设计。
除非所有继承的方法都有意义,否则不要使用继承
在覆盖方法时,不要改变预期的行为