Java 重写和隐藏


 


1编译时类型和运行时类型

 

Java的引用变量有两个类型,一个是编译时类型,一个是运行时类型

编译时类型由声明该变量时使用的类型决定

运行时类型由该变量指向的对象类型决定

如果编译时类型和运行时类型不一致,会出现所谓的多态。因为子类其实是一种特殊的父类,因此java允许把一个子类对象直接赋值给一个父类引用变量,无须任何类型转换,或者被称为向上转型,由系统自动完成。

 Father  f  =  new  Son();  SonFather的子类

引用变量f就会出现编译时类型和运行时类型不一致的情况 编译时是Father类型的 运行时是Son类型的

当变量的编译时类型和运行时类型不一致时,通过变量访问它所引用的对象的实例时,该实例变量的值由声明该变量的类型决定。

 

通过变量访问它所引用的对象的方法时,该方法的行为由所引用的对象实际类型所决定。

2、隐藏和覆盖

覆盖:子类重写父类的方法,要求方法名和参数类型完全一样(参数不能是子类),返回值和异常比父类小或者相同(即为父类的子类),访问修饰符比父类大或者相同。

覆盖是对于实例方法而言的

方法不能交叉覆盖:子类实例方法不能覆盖父类的静态方法;

                  子类的静态方法也不能覆盖父类的实例方法(编译时报错)

隐藏:父类和子类拥有相同名字的属性或者方法( 方法隐藏只有一种形式,就是父类和子类存在相同的静态方法)时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。

隐藏是对于静态方法和成员变量(静态变量和实例变量)而言的

(1)当发生隐藏的时候,声明类型是什么类,就调用对应类的属性或者方法,而不会发生动态绑定

  (2) 属性只能被隐藏,不能被覆盖

 (3)变量可以交叉隐藏:子类实例变量/静态变量可以隐藏父类的实例/静态变量

3、隐藏和覆盖的区别

1被隐藏的属性,在子类被强制转换成父类后,访问的是父类中的属性

  在无强制转换时子类要访问父类的属性使用super关键字

(2)被覆盖的方法,在子类被强制转换成父类后,调用的还是子类自身的方法

     子类要是想访问父类的方法,可以使用super关键字

RTTI(run time type identification,运行时类型检查)

RTTI只针对覆盖,不针对隐藏:因为覆盖是动态绑定,是受RTTI约束的,隐藏不受RTTI约束

运行时类型为引用变量所指向的对象的类型,编译时类型是引用变量自身的类型

4、常见的笔试面试题

  1. public class Test {  
  2.     public static void main(String[] args)  {  
  3.         Circle circle = new Circle();//本类引用指向本类对象  
  4.         Shape shape = new Circle();//父类引用指向子类对象(会有隐藏和覆盖)  
  5.           
  6.        System.out.println(circle.name);  
  7.        circle.printType();  
  8.        circle.printName();  
  9.        //以上都是调用Circle类的方法和引用  
  10.          
  11.         System.out.println(shape.name);//调用父类被隐藏的name属性  
  12.         shape.printType();//调用子类printType的方法  
  13.         shape.printName();//调用父类隐藏的printName方法   
  14.     }  
  15. }  
  16.    
  17. class Shape {  
  18.     public String name = "shape";  
  19.        
  20.     public Shape(){  
  21.         System.out.println("shape constructor");  
  22.     }  
  23.        
  24.     public void printType() {  
  25.         System.out.println("this is shape");  
  26.     }  
  27.        
  28.     public static void printName() {  
  29.         System.out.println("shape");  
  30.     }  
  31. }  
  32.    
  33. class Circle extends Shape {  
  34.     public String name = "circle"//父类属性被隐藏  
  35.        
  36.     public Circle() {  
  37.         System.out.println("circle constructor");  
  38.     }  
  39.      
  40.     //对父类实例方法的覆盖  
  41.     public void printType() {  
  42.         System.out.println("this is circle");  
  43.     }  
  44.       
  45.    //对父类静态方法的隐藏    
  46.     public static void printName() {  
  47.         System.out.println("circle");  
  48.     }  
  49. }  
public class Test {
    public static void main(String[] args)  {
    	Circle circle = new Circle();//本类引用指向本类对象
        Shape shape = new Circle();//父类引用指向子类对象(会有隐藏和覆盖)
        
       System.out.println(circle.name);
       circle.printType();
       circle.printName();
       //以上都是调用Circle类的方法和引用
       
        System.out.println(shape.name);//调用父类被隐藏的name属性
        shape.printType();//调用子类printType的方法
        shape.printName();//调用父类隐藏的printName方法 
    }
}
 
class Shape {
    public String name = "shape";
     
    public Shape(){
        System.out.println("shape constructor");
    }
     
    public void printType() {
        System.out.println("this is shape");
    }
     
    public static void printName() {
        System.out.println("shape");
    }
}
 
class Circle extends Shape {
    public String name = "circle"; //父类属性被隐藏
     
    public Circle() {
        System.out.println("circle constructor");
    }
   
    //对父类实例方法的覆盖
    public void printType() {
        System.out.println("this is circle");
    }
    
   //对父类静态方法的隐藏  
    public static void printName() {
        System.out.println("circle");
    }
}
  1. 运行结果:  
运行结果:
  1. shape constructor  
  2. circle constructor  
shape constructor
circle constructor
  1. circle  
  2. this is circle  
  3. circle  
circle
this is circle
circle
  1. shape  
  2. this is circle  
  3. shape  
shape
this is circle
shape

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值