Java面向对象基础(4-继承)
继承
继承是面向对象编程中一种非常强大的代码复用机制,即在已有基础上进行功能的拓展。
首先我们先看一下没有使用继承的两个类Person类和Student类。
class Person {
private String name;
private int age;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
class Student{
private String name;
private int age;
private int score;
public int getScore() {...}
public void setScore(int score) {...}
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
这时候我们很容易就看出来,
Studnet类中很多功能和Person类中一样,只是多了一个score字段和getScore()、setScore()方法。那么我们怎样可以在Student中不写重复的代码?这时候就用到了继承。
然后我们再看一下用继承写的这两个类。
class Person {
private String name;
private int age;
public String getName() {...}
public void setName(String name) {...}
public int getAge() {...}
public void setAge(int age) {...}
}
class Student extends Person{
private int score;
public int getScore() {...}
public void setScore(int score) {...}
}
继承是通过extends关键词来实现的。
通过两段代码的对比,我们很容易发现,继承可以实现代码的复用,即去除相同功能代码的重复书写,可以使Student类在Person类的基础上进行功能的拓展。
注意:子类自动获得了父类的所有字段,严禁定义和父类重名的字段!
在OOP术语中,我们把
Person类称为超类(super class),父类(parent class),基类(base class)
Student类称为子类(subclass),扩展类(extended class)
- 继承树
在Java中,我们没有明确写extends的类,编译器会自动加上extends Object。任何类,除了Object,都会继承自某个类。
Java只允许一个class继承自一个类,因此,一个类有且仅有一个父类。只有Object特殊,没有父类。
Java允许单继承(B类继承A类),多重继承(C类继承B类,B类继承A类),不同类继承同一个类(B类继承A类,C类继承A类)。
但是,Java不支持多继承(C类继承A类,C类继承B类)。
Java的特性:
- 子类拥有父类非private的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
- protected
- 继承导致子类无法访问父类
private字段或者private方法,为了让子类可以访问父类的字段,我们可以把父类的private改为protected,用protected修饰的字段可以被子类访问。 - 因此,
protected关键词可以把字段和方法的访问权限控制在继承树内部,一个protected字段或者方法可以被其子类,以及子类的子类所访问。
- super
super关键字表示父类(超类)。子类引用父类字段时,可以用super.fieldName。
- 向上转型
定义:把一个子类类型安全的变为父类类型的赋值,被称为向上转型(upcasting)。
例如:
Person p = new Student();
继承树是Student > Person > Object。所以,可以把Student类型转型成Person或者更高层次的Object。
- 向下转型
定义:如果把一个父类类型强制的转型成子类类型,就是向下转型(downcasting)。
例如:
Person p1 = new Student(); // upcasting , ok
Person p2 = new Person();
Student s1 = (Student) p1; //downcasting,ok
Student s2 = (Student) p2; //runtime error!
Person类型p1实际指向Student实例,Person类型p2实际指向Person实例。在向下转型的时候,把p1转型成Student会成功,是因为p1确实指向Student实例,把p2转型成Student会失败,因为p2的实际类型是person,不能把父类转变成子类,因为子类的功能比父类的多,多的功能无法凭空变出来。
因此,向下转型很可能会失败。失败的时候,Java虚拟机会报ClassCastException。
- instanceof
instanceof实际上是用来判断一个变量是否是指定类型,或者是这个类型的子类。如果一个引用变量为null,那么对任何instanceof的判断都为false。
instanceof主要是用来避免向下转型出错,可以先判断一个实例是否是某种类型。例如:
Person p = new Student();
if(p instanceof Student){
Student s = (Student)p;
}

浙公网安备 33010602011771号