继承就是子类继承父类的特征和行为,使得子类对象(实例)具备父类的实例域和方法,或子类从父类继承方法,使得子类具备父类相同的行为。java
关键字 extends 代表正在构造的新类派生于一个已存在的类。ide
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; } //more method ...... }
尽管 Employee 类是一个超类,但并非由于它位于子类之上或者拥有比子类更多的功能。偏偏相反,子类比超类拥有的功能更加丰富。在 Manager 类中,增长了一个用于存储奖金信息的域,以及一个用于设置这个域的方法:this
public class Manager extends Employee{//extends继承Employee类 ... private double bonus; public void setBonus(double bonus) { this.bonus = bonus; } }
然而,尽管在 Manager 类中没有显式地定义 getName 和 getHireDay 等方法,但属于 Manager 类的对象却可使用它们,这是由于 Manager 类自动地继承了超类 Employee 中的这些方法。一样,从超类中还继承了 name、salary 和 hireDay 这 3 个域。这样一来,每一个 Manager 类对象就包含了4个域:name、salary、hireDay 和 bonus。编码
在经过扩展超类定义子类的时候,仅须要指出子类与超类的不一样之处。所以在设计类的时候,应该将通用的方法放到超类中,而将具 有特点用途的方法放在子类中,这种将通用的功能放到超类的作法,在面向对象程序设计中十分广泛。
然而,超类中的有些方法对子类 Manager 并不必定适用。例如,在 Manager 类中的 getSalary 方法应该返回薪水和奖金的总和。为此,须要提供一个新的方法来覆盖(override)超类中的这个方法:设计
@Override public double getSalary() { return salary + bonus;//won't work }
然而,这个方法并不能运行。这是由于 Manager 类的 getSalary 方法不能直接地访问超类的私有域。也就是说,尽管每一个 Manager 对象都拥有一个名为 salary 的域,但在 Manager 类的 getSalary 方法中并不可以直接地访问 salary 域。只有 Employee 类的方法才可以访问私有部分。若是 Manager 类的方法必定要访问私有域,就必须借助共有的接口,Employee 类中的共有方法正式这样一个接口。code
@Override public double getSalary() { return super.getSalary() + bonus; }
super 关键字有两个用途:一是调用超类的方法,二是调用超类的构造器。 super 不是一个对象的引用,不能将 super 赋给另外一个对象变量,它只是一个指示编译器调用超类方法的特有关键字。
因为 Manager 类的构造器不能访问 Employee 类的私有域,因此必须利用 Employee 类的构造器对这部分私有域进行初始化,咱们能够经过 super 实现对超类构造器的调用。使用 super 调用构造器的语句必须是子类构造器的第一条语句。对象
public class Animal { public Animal() { System.out.println("--Animals--"); } public static int printInit(String s) { System.out.println(s); return 30; } } public class Bird extends Animal { private static int B = Animal.printInit("static Bird region init"); public Bird(){ System.out.println("--Bird--"); } } public class Parrot extends Bird { public Parrot(){ super(); System.out.println("--Parrot--"); } public static void main(String[] arg) { Parrot parrot = new Parrot(); } }
运行结果:继承
--Animals-- --Bird-- --Parrot--
纯继承关系是纯粹的“is-a”(是一种)关系,由于一个类的接口已经肯定了它应该是什么。继承能够确保全部的导出类具备基类的接口,且绝对不会少。基类能够接收发送给导出类的任何消息,由于两者有着彻底相同的接口。接口
* Java 语言的继承是单继承,不容许一个类继承多个父类。 * java支持多层继承(继承体系)。 * 子类和父类是一种相对概念。 * 备注:顶层父类是Object类,全部的类默认都继承Object类。
1. 子类只能获取父类非私有成员 2. 子父类的成员变量的名字不同时,直接获取父类的成员变量 3. 子父类中成员变量名字是同样的 * 就近原则,谁离我近我就用谁 * 若是有局部变量就使用局部变量 * 若是没有局部变量,有子类的成员变量就使用子类的成员变量 * 若是没有局部变量和子类的成员变量,有父类的成员变量就使用父类的成员变量 * 备注:父类中的成员变量是非私有的,子类才能够直接访问。若父类中的成员变量私有了,子类不能直接访问的。 一般编码时,咱们通常遵循封装的原则,能够在父类中提供公共的setXxx()和getXxx()方法。
例如:get
public class ExtendsDemo2 { public static void main(String[] args) { Kid k = new Kid(); k.show(); } } class Dad{ String name="大葱"; } class Kid extends Dad{ String name="二葱"; public void show() { String name = "三葱"; System.out.println(super.name); System.out.println(this.name); System.out.println(name); } }
1. 子父类的成员方法的名字不同时,直接获取父类的成员方法 2. 子父类中成员方法名字是同样的 * 成员方法重名---重写(Override) * 方法重写:子类出现于父类如出一辙的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效应 也称为重写或者复写。声明不变,从新实现。 *重写的应用 子类能够根据须要,定义特定于本身的行为,即沿袭了父类的功能名称,又能根据子类的须要从新实现父类 的方法,从而进行扩展加强。 * 方法额重载:在一个类中,有多个重名的方法,可是其参数不同 (参数的个数,参数的类型,参数的顺序),和返回值无关
备注: 1.子类方法重写覆盖父类方法时,必须保证权限大于等于父类的权限。 2.子类方法重写父类方法时,返回值类型,方法名和参数列表必须如出一辙。 在没有使用@Override时,子类定义父类方法时,方法名和参数列表可变,返回值类型不可变。
在面向对象语言中,继承是必不可少的、很是优秀的语言机制,它有以下优势: