- Java中类的分类
已经存在的类:超类(superclass),父类(parent class),基类(base class);
新类:子类(subclass),派生类(derived class),孩子类(child class),孩子类(child class)
关键字extends表明正在构建的新类派生于一个已经存在的类
如果没有extends句子,该类默认为java.lang.Object的子类【所有的类都是直接或间接继承java.lang.Object得到的】
- 继承的基本概念:用来延续具体化概念,继承已经存在的类就是继承这些类的方法和域。
- 子类继承父类或超类的属性和方法。
因此,通用的方法放在超类中,具有特殊用途的方法放在子类
public class Manager extends Employee
{
//添加Manager类特有的方法和域
private double bonus;
...
public void setBonus(double salary)
{
this.bonus=bonus;
}
}
/**
*经理集合是员工集合的子类,员工集合是经理集合的超类
*子类Manage类自动继承了超类Employee的name,salary,hireDay域,以及对应的公有方法
*/
但是,有时候超类的某些方法并不适用于子类,这时候需要用别的方法覆盖超类中的这些不适用的方法
由于子类的方法不能直接访问超类的私有域,因此,子类需要访问超类的私有域时必须借助公有接口,父类的公有方法正是这样的接口。调用超类的方法或者构造器时,使用关键字super
使用格式:super.所调用的超类的方法()
/**
*例如Manager类调用超类Employee中的getSalary方法
*/
public double getSalary()
{
double baseSalary=super.getSalary();
return baseSalary+bonus;
}
综上所述,在子类中可以增加域,增加方法,以及覆盖超类的方法;而不能删除继承的任何域和方法。
2.类一定有构造器,而构造器不能继承,只能调用,子类的构造器一定继承父类的构造器。
由于子类构造器不能直接访问超类的私有域,对所继承超类的域进行初始化时得调用父类的构造器。子类构造器调用父类的构造器用关键字super(参数列表),使用super调用构造器放在子类构造器的第一条,借此构造器对超类的部分私有域进行初始化。
public Manager(String name,double salary,int year,int month,int day)
{
super(name,salary,year,month,day)//可简化成super(n,s,year,month,day),调用超类Employee中含有对应参数的域。
bonus=0;
}
若子类构造器没有显式地调用超类的构造器,则系统自动调用超类默认的构造器,若超类没有不带参数的构造器,且子类没有调用超类的其他构造器,则编译器将会报错。
区别关键字this,super
相同点:都可以调用构造器,构造参数既可以传递给本类(this)的其他构造器,还可以传递给超类(super)的构造器
不同点:
this:一,引用隐式参数;二,调用该类的其他构造器、
super:一,调用超类的方法;二,调用超类的构造器
package againtry;
import java.time.*;
public class Employee
{
private String name;
private double salary;
private LocalDate hireDay;
public Employee(String name, double salary,int year,int month,int day)
{
this.name=name;
this.salary=salary;
hireDay=LocalDate.of(year,month,day);
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public LocalDate getHireDay()
{
return hireDay;
}
//method
public void raiseSalary(double byPercent)
{
//Scanner in=new Scanner(System.in);
double raise=salary*byPercent/100;
salary+=raise;
}
}
package againtry;
public class Manager extends Employee{
private double bonus;
/**
*
* @param name
* @param salary
* @param year
* @param month
* @param day
*/
public Manager(String name,double salary,int year,int month,int day) {
super(name,salary,year, month,day);
bonus=0;
}
public double getSalary()
{
double baseSalary=super.getSalary();
return baseSalary+bonus;
}
public void setBonus(double b)
{
bonus=b;
}
}
package againtry;
/**
* this program demonstrate inheritance
* @version 2019/8
* @author lison
*
*/
public class Managertest {
public static void main(String[] args) {
Manager master=new Manager("Windy",8000,2017,1,20);
master.setBonus(5000);
Employee[] staff=new Employee[3];
staff[0]=master;
staff[1]=new Employee("Jastin",5000,2016,3,10);
staff[2]=new Employee("Vinase",6000,2019,4,4);
for(Employee e:staff)
System.out.println("name="+e.getName()+"salary="+e.getSalary()+"hireDay="+e.getHireDay());
}
}
运行结果:
父类对象和子类对象的转换
存在继承关系的父类对象和子类对象在一定条件下也可以相互转换
1)子类对象可以被视为父类的一个对象,而父类对象不能当作某一个子类的对象
2)一个方法的形式参数定义的是父类对象,调用这个方法时可以用子类对象作为实参
3)强制类型转换(casting):父类对象的引用强制转换为子类对象的引用,即父类对象引用指向一个子类对象
如:Student.java