关于java继承问题上重写(覆盖)以及隐藏区别联系的个人见解

本文通过示例详细解析了Java中的方法覆盖与隐藏的区别,包括实例方法与静态方法的不同行为,以及如何通过super关键字访问父类被隐藏的成员。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

讲隐藏和覆盖之前先看两个概念:静态类型动态类型

任何一个引用变量都有两个类型:一个叫静态类型,也就是定义该引用变量的类型;另一个叫动态类型,也就是该引用实际指向的对象类型。

比如对于两个类A和类B,有:A a=new B();

那么,引用a的静态类型就是A,动态类型就是B

先看一段示例

 

class Parent  
{  
    public static String kind="javastudy.extendsstudy.parent";  
    public static int age=50;  
    public String name="Parent";  
  
    //静态方法,返回包名  
    public static String getKind()  
    {  
        System.out.println("parent的getKind()方法被调用了");  
        return kind;  
    }  
  
    //静态方法,返回年龄  
    public static int getAge()  
    {  
        System.out.println("Parent的getAge()方法被调用了");  
        return age;  
    }  
  
    //实例方法,返回姓名  
    public String getName()  
    {  
        System.out.println("Parent的getName()方法被调用了");  
        return this.name;  
    }  
  
}  
  
  
//子类  
class Child extends Parent  
{  
    public static String kind="javastudy.extendsstudy.child";  
    public int age=25;  
    public String name="child";  
  
    //隐藏父类静态方法  
    public static String getKind()  
    {  
        System.out.println("child的getkind()方法被调用了");  
        return kind;  
    }  
      
    //获取父类包名  
    public static String getParentKind()  
    {  
        return Parent.kind;  
    }  
      
    //覆盖父类实例方法  
    public String getName()  
    {  
        System.out.println("child的getName()被调用了");  
        return this.name;  
    }  
      
    //获取父类名称  
    public String getParentName()  
    {  
        return super.name;  
    }  
    /* 
     *错误,实例方法不能覆盖父类的静态方法 
    public int getAge() 
    { 
        return this.age; 
    } 
    */  
}  
public class chongxieyuyincang {

	public static void main(String[] args) {
		  Child child=new Child();  
	        System.out.printf("子类名称:%s,年龄:%d,包名:%s%n",child.name,child.age,child.kind);  
	        //输出:子类名称:child,年龄:25,包:javastudy.extendsstudy.child  
	  
	        //把child转换成parent对象  
	        Parent parent=child;  
	  
	        System.out.printf("转换后的名称:%s,年龄:%d,包名:%s%n",parent.name,parent.age,parent.kind);  
	        //输出:转换后的名称:Parent,年龄:50,包:javastudy.extendsstudy.parent  
	  
	        System.out.printf("子类访问父类被隐藏的实例变量name:%s%n",child.getParentName());  
	        //输出:子类访问父类被隐藏的实例变量name:Parent  
	          
	        System.out.printf("子类访问父类被隐藏的静态变量kind:%s",child.getParentKind());  
	        //输出:子类访问父类被隐藏的静态变量kind:javastudy.extendsstudy.parent  
	  
	        child.getName();  
	        //输出:child的getName()被调用了  
	  
	        //**************注意看这个方法,返回的还是子类的getName  
	        parent.getName();  
	        //输出:child的getName()被调用了  
	  
	        child.getKind();  
	        //输出:child的getkind()方法被调用了  
	  
	        parent.getKind();  
	        //输出:parent的getKind()方法被调用了    	

	}

}
子类名称:child,年龄:25,包名:javastudy.extendsstudy.child
转换后的名称:Parent,年龄:50,包名:javastudy.extendsstudy.parent
子类访问父类被隐藏的实例变量name:Parent
子类访问父类被隐藏的静态变量kind:javastudy.extendsstudy.parentchild的getName()被调用了
child的getName()被调用了
child的getkind()方法被调用了
parent的getKind()方法被调用了

1.同名的实例方法被覆盖 ,同名的静态方法被隐藏 ,child类的getName实例方法覆盖 了parent的getName实例方法,chind的getKind方法隐藏 了parent类的getKind方法

2.隐藏 和覆盖 的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏 的变量和方法,而不能访问父类被覆盖 的方法

3.如果需要访问父类被隐藏 的部分,加上super就好了,比如访问父类的name,写上super.name就好了

 

这点儿请注意,就是变量只会被隐藏 不会被覆盖 ,无论他是实例变量还是静态变量,而且,子类的静态变量可以隐藏 父类的实例变量,子类的实例变量可以隐藏 父类的静态变量

父类的成员变量只会被隐藏,而且支持交叉隐藏(比如静态变量被非静态变量隐藏)。父类的静态方法只会被静态方法隐藏,不支持交叉隐藏。父类的非静态方法会被覆盖,但是不能交叉覆盖。

下面一个伪代码是自己写的,以便参考

//首先建立父子类,animal和cat ,然后对A函数进行静态隐藏
//对B函数进行重写,这里我就不写了
public class cat {

	public static void main(String[] args) {
	//接下来进行创建实例对象
		Cat mycat=new Cat();
		Animal myanimal=new mycat;
		Animal.A();
		myanimal.A();
		Cat.A();
		myanimal.B();
		mycat.B();

	}

}
//这里面,类cat重写了类animal的实例方法,隐藏了animal类方法
//在主函数中农,创建了一个cat的实例对象,调用了animal,myanimal,cat的类方法A
//HE MYANIMAL的实例方法B
//输出结果 父父子子子
//从上到下调用的依次是,类的类方法,对象的类方法,类的类方法
//对象的实例方法,对象的实例方法

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值