对象转型casting
1.一个基类的引用类型可以指向其子类的对象
2.一个基类的引用指向子类的对象时不可以访问其子类对象新增加的成员(属性和方法)
3.可以使用 instanceof 类名来判断该引用变量所指向的对象是否属于该类或该类的子类
example
class Animal {
public String name;
Animal(String name){
this.name = name;
}
}
class Dog extends Animal{
public String further_color;
Dog(String name, String further_color){
super(name);//这里是有参数的
this.further_color = further_color;
}
}
class Cat extends Animal{
public String eye_color;
Cat(String name, String eye_color){
super(name);
this.eye_color = eye_color;
}
}
public class TestCasting{
public static void main(String args[]){
Animal a = new Animal("Jerry");
Dog b = new Dog("Speike", "white");
Cat c = new Cat("Tom", "yellow");
System.out.println(a.name);
System.out.println(b.name);
System.out.println(c.name);
System.out.println(a instanceof Animal);
System.out.println(b instanceof Animal);
System.out.println(c instanceof Animal);
System.out.println(a instanceof Cat);
a = new Dog("bigyellow", "yellow");//a是Animal的引用类型,虽然现在让它指向Dog类型,但实际指向Animal
System.out.println(a.name);//Animal的引用类型指向子类Dog
//System.out.println(a.further_color);//无法调用新增方法
System.out.println(a instanceof Animal);//true
System.out.println(a instanceof Dog);//true
Dog d1 = (Dog) a;//强制转换
System.out.println(d1 instanceof Dog);
}
}
多态(动态绑定)
在执行期间判断所引用对象的实际类型,根据实际类型调用相应方法
多态的三大条件:
1.继承
2.重写
3.父类引用指向子类对象
此时,当我们调用父类中被重写的方法,实际调用的是哪个子类对象就使用该类的方法
class Animal{
private String name;
Animal(String name){
this.name = name;
}
public void enjoy(){
System.out.println("Animal 叫");
}
}
class Cat extends Animal{
private String eye_color;
Cat (String name, String eye_color){
super(name);
this.eye_color = eye_color;
}
public void enjoy(){
System.out.println("Cat 叫");
}
}
class Dog extends Animal{
private String further_color;
Dog(String name, String further_color){
super(name);
this.further_color = further_color;
}
public void enjoy(){
System.out.println("Dog 叫");
}
}
class Lady{
private String name;
private Animal pet;
Lady(String name, Animal pet){
this.name = name;
this.pet = pet;
}
public void MypetEnjoy(){
pet.enjoy();
}
}
public class Test{
public static void main(String args[]){
Cat mm1 = new Cat("Tom", "yellow");
Dog mm2 = new Dog("Speike","white");
Lady m1 = new Lady("m1", mm1);//父类引用调用子类对象,与对象转型相似
Lady m2 = new Lady("m2", mm2);
m1.MypetEnjoy();
m2.MypetEnjoy();
}
}
//mm1被当做Animal传递进来,正常来说 m1.MypetEnjoy() 输出的应该是 “Animal 叫”,但是当调用 enjoy() 方法时,我们会根据实际类型Cat来确定,而不是根据引用类型Animal来确定
//多态的好处在于,我们没必要在 MypetEnjoy() 中判断使用(重写)哪种方法
抽象类
抽象类必须被继承,抽象方法必须被重写(它本身是残缺的,无法实现抽象方法,因此不能被实例化( new class),抽象方法会在子类中实现),
在上面的example中
class Animal{
private String name;
Animal(String name){
this.name = name;
}
public void enjoy(){
System.out.println("Animal 叫");//其实这种方法只需要定义(满足重写的条件),但是不需要实现,因为它必定是会被重写的
}
}
但是如果注释掉,变成只有定义而无实现的,因此赋予关键字 abstract,成为抽象方法,其类变成抽象类,
abstract class Animal{//标识为抽象类
private String name;
Animal(String name){
this.name = name;
}
public abstract void enjoy()//标识为抽象方法
}
final关键字
抽象方法需要被重写
但是若无需重写,不能修改就要使用Final
final 可以修饰变量的值(成员变量,局部变量),方法,类
由final修饰的都不能被修改
example
class T{
final int i =8;
public void m(final int j){
j = 9;//无法为最终变量j分配值
}
}
class TT{
final int i =8;
public final void m(){
j = 9;//无法为最终变量j分配值
}
}
class TTT extends TT{
public final void m(){//TTT中的m()无法覆盖TT中的m()
}
}
final class TTTT{
}
class TTTTT extends TTTT{//无法从最终TTTT进行继承
}
public class TestFinal{
public static void main(String args[]){
T t = new T();
t.i = 8;//无法为最终变量i分配值
}
}