
继承机制是面向对象程序设计中使代码能够重复使用的重要手段,它允许程序员在保持原有类特性的基础上,进行扩展、增加新功能,由此产生的类,称为派生类。 继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。
//(修饰) 子类 extends 父类 {...}
public class Animal { //父类或基类或超类
public String name;
public int age;
public void eat() {
System.out.println(this.name + " is eating food.");
}
}
public class Cat extends Animal{ //子类或派生类
public void meow() {
System.out.println(this.name + " is meowing.");
}
}
public class Dog extends Animal{
public void bark() {
System.out.println(this.name + " is barking.");
}
}
class Main {
public static void main(String[] args) {
Dog dog = new dog();
System.out.println(dog.name);
System.out.println(dog.age);
//Dog类中并没有定义name和age这两个成员属性,说明是从父类继承得来的
System.out.println(dog.eat());
//同理,Dog类也继承了父类的eat方法
}
}注意:
当子类中含有与父类名字相同的成员变量时,访问的是哪一个?
class A {
public int a;
public int b;
}
class B extends A {
public int a;
}
class Main {
public static void main(String[] args) {
B b = new B();
System.out.println(b.a);
}
}当子类中没有父类中的成员时,访问的是父类的成员;当子类中有父类中没有的成员时,直接访问子类的成员;当子类中有与父类同名的成员时,优先访问子类的成员。
若子类中有父类的同名成员,且我想要访问父类的成员,这时候我们就可以用到super关键字.
class A {
public int a;
public int b;
}
class B extends A {
public int a;
public void method() {
super.a = 10; //此行代码修改的是父类a的值
}
}注意:
子类构造方法调用之前, 必须先调用父类的构造方法.
class Base {
public Base() {
System.out.println("Base");
}
}
class Derived extends Base {
public Derived() {
//super();
System.out.println("Derived");
}
}
class Main {
public static void main(String[] args) {
Derived derived = new Derived();
}
}运行后结果为:
Base Derived
注意:
前面类和对象中我们讲过未继承状态下实例代码块、静态代码块和构造方法的执行顺序,我们再将一下有了继承关系后的执行顺序。
class Person {
public String name;
public int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("执行了Person的构造方法");
}
{
System.out.println("执行了Person的实例代码块");
}
static {
System.out.println("执行了Person的静态代码块");
}
}
class Student extends Person {
public String name;
public int age;
public Student(String name,int age) {
super(name,age);
System.out.println("执行了Student的构造方法");
}
{
System.out.println("执行了Student的实例代码块");
}
static {
System.out.println("执行了Student的静态代码块");
}
}
class Main {
public static void main(String[] args) {
Student stu = new Student("Zhangsan",20);
System.out.println("============================");
Student stu = new Student("Lisi",19);
}
}
//执行结果
执行了Person的静态代码块
执行了Student的静态代码块
执行了Person的实例代码块
执行了Person的构造方法
执行了Student的实例代码块
执行了Student的构造方法
============================
执行了Person的实例代码块
执行了Person的构造方法
执行了Student的实例代码块
执行了Student的构造方法由此可以得出继承关系的执行顺序为:

class Base {
private int a;
protected int b;
public int c;
int d;
}
//同一个包中的子类
class Derived1 extends Base {
public void method() {
//super.a = 10; 编译报错,父类的private成员在同一个包中的子类中不可访问
super.b = 20; //在同一个包中子类可以访问父类的protected成员
super.c = 30; //在同一个包中子类可以访问父类的public成员
super.d = 40;
}
}
//不同包的子类
class Derived2 extends Base {
public void method() {
//super.a = 10; 编译报错,父类的private成员在同一个包中的子类中不可访问
super.b = 20; //在同一个包中子类可以访问父类的protected成员
super.c = 30; //在同一个包中子类可以访问父类的public成员
//super.d = 40; 编译报错,在不同包的子不可访问父类默认权限的成员
}
}
//不同包中的类
class Derived3 {
public void method() {
//super.a = 10; 编译报错,父类的private成员在同一个包中的子类中不可访问
//super.b = 20; 编译报错,在不同包中非子类不可访问Base类的protected成员
super.c = 30; //在同一个包中子类可以访问父类的public成员
//super.d = 40; 编译报错,在不同包的子不可访问父类默认权限的成员
}
}为了尽量对外隐藏实现细节体现封装性,建议将所有的字段设置为private,将所有的方法设置为public。
Java中有多种继承方式:单继承(一个父类一个子类)、多层继承、多个子类继承自同一个父类。但是不支持多继承(一个类继承自多个父类)。
若想要从语法上限制继承,可以使用 final 关键字,被final修饰的类不能再被其他类继承。
完