一、继承
Java中使用关键字extends表示继承,Java中所有的继承都是公共继承。
class Manager extends Employee
{
//............
}
子类可以增加域、增加方法或者覆盖(重写)父类的方法,但不可以删除父类的任何域和方法。
子类覆盖父类方法时,访问权限不能比父类低,也即父类方法为public,则子类覆盖父类的方法也得为public。
在子类中,如果想调用父类中的方法,而不是当前类的方法,则可以使用关键字super。
public float getSalary()
{
return super.getSalary() + bonus;
}
当然,对于子类的构造器,如果没有显式的调用父类的构造器,则会自动调用父类默认的构造器(没有参数的构造器)。
如果此时父类没有默认的构造器,则此时编译器会因为找不到父类的构造器而报错。
class Employee
{
Employee(String name,int id)
{
//....................
}
}
class Manager extends Employee
{
Manager(String name,int id) //子类的构造方法没有显式调用父类构造器,且父类无默认的构造器,所以编译时会报错。
{
super.name = name ;
super.id = id;
}
}
多态:
一个对象变量可以引用多种实际类型的现象被称为多态。
Manager TempM = new Manager();
Employee TempE = TempM ;
TempE是Employee类型的,TempM是Manager类型的,Manager类继承了Employee类。
TempE不能使用Manager类的特有方法,也即父类引用不能使用子类的特有方法。子类转为父类的引用不需要强制转换。
public class Test21
{
public static void main(String[] args)
{
Manager TempM = new Manager("zhangs",001);
TempM.setBonus(500);
TempM.tobeString();
System.out.println(TempM.getSalary());
Employee[] staff = new Employee[3] ;
staff[0] = TempM ;
staff[0].tobeString();
// staff[0].setBonus(1000); //staff[0]是Employee类型,不能调用子类Manager的特有方法
System.out.println(staff[0].getSalary());
staff[1] = new Employee("lisi",002);
staff[1].tobeString();
System.out.println(staff[1].getSalary());
staff[2] = new Employee("wange",003);
staff[2].tobeString();
System.out.println(staff[2].getSalary());
staff[0] = new Employee("hj",004);
staff[0].tobeString();
System.out.println(staff[0].getSalary());
TempM.tobeString();
Employee TempM1 = new Manager("zhangs1",005);
System.out.println(TempM1.getSalary());
}
}
class Employee
{
public Employee(String name,int id)
{
this.name = name;
this.id = id;
nextId++;
salary=1000.0f;
}
public void tobeString()
{
System.out.println(name+id+nextId);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public float getSalary()
{
return salary;
}
public void setSalary(float salary)
{
this.salary = salary;
}
public static int getNextId()
{
return nextId ;
}
private String name;
private int id;
private static int nextId = 0;
private float salary ;
}
class Manager extends Employee
{
Manager(String name,int id)
{
super(name,id);
bonus=0 ;
}
public void tobeString()
{
System.out.println(super.getName()+super.getId()+super.getNextId()+bonus);
}
public float getSalary()
{
return super.getSalary()+bonus;
}
public void setBonus(float bonus)
{
this.bonus=bonus;
}
public float getBonus()
{
return bonus;
}
private float bonus;
}
动态绑定(未完全明白,JAVA2核心技术150页):
所谓动态绑定,也即编译器寻找具体执行方法的过程。
1、编译器查看对象的声明类型和方法名。
例如调用方法X.f(),X是声明为A类对象,则编译器会搜索A类中所有方法名为f的方法,以及搜索类A的父类中,所有方法名为f且为public访问的方法。
2、编译器通过具体方法的参数类型,选择完全匹配的方法。1和2成为重载解析。
3、如果方法是final,private,static或者构造器,则编译器会很准确的找到该调用的方法,称为静态绑定。
4、程序运行,虚拟机会调用所引用对象的实际类型最合适的那个类的方法。这其实是一个搜索对应方法的过程,搜索耗时间,所以虚拟机会预先建立一个方法表
阻止继承:
对类使用final修饰或对方法使用final修饰可以阻止该类被继承或者该方法再被继承。
对象声明为final之后,只有其中的方法自动变为final,但域不会变为final。
强制类型转换:
将一个类型转换为另外一个类型的过程称为类型转换。
在类型强制转换过程中,如果条件不满足,可能抛出异常。
在进行类型转换之前,一般需要检查一下是否能够成功进行类型转换,使用instanceof运算符检查,如果不能转换,则编译器就不会执行转换操作。
if(staff instanceof Manager)
{
TempM = (Manager)staff ;
}
类型转换
1、只能在编译层次内进行类型转换。
2、将超类转为子类之前,需要使用instanceof进行检查。