[JavaSE]面向对象特性之继承

文章目录

  • 继承(inherit)
    • 基本思想
    • 超类和子类
    • 覆盖方法
    • 子类构造器
    • 多态
    • 阻止继承:final类和方法
    • 强制类型转换

继承(inherit)

先上一段代码!

class A{
	...
}
class B extends A{		//B类继承了A类
	...
}

继承使用关键字extends,意为扩展的意思。extends关键字就是在构造新类派生于一个已存在的类。

基本思想

继承的基本思想就是基于已有的类创建新的类

作用:继承已存在的类可以复用这个类的方法,而且可以在此基础上增加新的方法和字段,使新的类能够适应新的情况。

超类和子类

在继承中最关键的名词就是超类和子类了。已存在的类就是超类,而新类就是子类。
超类又可以称之为父类或者基类。子类又可以称之为派生类。

覆盖方法

super关键字
当我们想使用超类的方法时,可以利用super.方法名的格式来调用。
例如:

class Employee{
	private double salary; 
	...
	public double getSalary(){
		return salary;
	}
}
class Manager extends Employee{
	private double bonus = 100; //经理的额外奖金
	...
	public double getSalary(){
		return super.getSalary() + bonus;
	}
}

上例中经理不同与普通员工之处有一个奖金,所以getSalary()方法需要改写也就是覆盖了员工类的getSalary方法。而如果直接返回salary + bonus的话是错误的,因为经理类不能直接访问员工类的salary字段(因为它是私有的),这是就要使用super关键字来解决这个问题。

子类构造器

由于子类的构造器不能访问父类的私有字段,所以必须通过一个构造器来初始化这些私有字段。那么就可以用特殊的super语法来调用这个构造器。

注意:使用super调用构造器的语句必须是子类构造器的第一条语句。

例如:

public class Person{
	private int age;
	private String name;
	...
	public Person(String name){
		this.name = name;
	}
	...
}
public class Student extends Person {

    private int score;
    private int sno;


    public Student(String name) {
        super(name);               
        //含义:调用Person类中带有name参数的构造器。
    }
    ...
}

提示:
如果子类的构造器没有显式地调用父类的构造器,那么会自动调用超类的无参构造器。如果超类没有无参构造器,并且子类中又没有显式地调用超类的其他构造器,那么就会报错。

多态

多态(ploymorphism)也是由于继承而产生出的一个概念。在Java中,对象变量是多态的,一个超类类型的变量既可以引用自己的对象,也可以引用任何一个子类的对象。

简单来说,任何超类对象都可以用子类对象来替换。
例如

class Employee{
    ...
}
class Manager extends Employee{
    ...
}
Employee e;
e = new Employee(...);
e = new Manager(...);

注意:
不能将超类的引用赋予子类的变量。

继承虽然可以提高代码的复用性,但同时也有缺点,它会提高使得程序的耦合度增高,因为当父类被修改,子类也会收到影响。所以有时会用final关键字来阻止继承发生。

阻止继承:final类和方法

  • final类
    当将一个类定义为final,则说明这个类不允许被扩展,不允许拥有任何子类。
  • final方法
    当将一个方法定义为final,则这个类中的这个final方法就不允许被子类覆盖这个方法。

(当一个类被定义为final时,其方法自动成为final方法,但不包括字段)

强制类型转换

进行强制类型转换的唯一原因是:要在暂时忽视对象的实际类型之后使用对象的全部功能。

强制类型转换允许将一个子类的引用赋给一个超类变量,但不允许将超类的引用赋给一个子类变量。

一个好习惯: 在强制类型转换之前,使用instanceof操作符查看是否能够成功转换。

例:

if ( staff[1] instanceof Manager ){
    boss = (Manager) staff[1];
    ...
}

注意:

  • 只能在继承层次内进行强制类型转换。
  • 在将超类强制类型转换为子类之前,应该使用instanceof进行检查。

只要没有捕获ClassCastException(类型转换异常),程序就会终止。

一般情况下,尽量少使用强制类型转换和instanceof运算符。

写在最后:
那么什么时候使用继承呢?

当你确实需要一个继承关系,并且可以用"is a"来描述。

你可能感兴趣的:(java,编程语言)