Java 继承中静态方法和变量的 覆盖隐藏问题

所谓静态,就是在运行时,虚拟机已经认定此方法和变量属于哪个类。 

我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊,但是在面试或者是SCJP认证题中围绕这些是会经常碰到的,所以这里来讨论下

 

首先我们来看几个概念

隐藏 :child隐藏了parent的变量和方法,那么,child不能访问parent被隐藏的变量或者方法,但是,讲B转换成A中,可以访问A被隐藏的变量或者方法

覆盖 :child覆盖了parent的变量或者方法,那么,child不能访问parent被覆盖的变量或者方法,将child转换成parent后同样不能访问parent被覆盖的变量或者方法

 

首先看一下JAVA中方法和变量在继承时的覆盖和隐藏规则

1.父类的实例变量和静态变量能被子类的同名变量隐藏

2.父类的静态方法被子类的同名静态方法隐藏

3.父类的实例方法被子类的同名实例变量覆盖

 

还有几点需要注意的是

1.不能用子类的静态方法隐藏 父类中同样标示(也就是返回值 名字 参数都一样)的实例方法

2.不能用子类的实例方法覆盖 父类中同样标示的静态方法

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

//父类
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;
	}
	*/
}


class Test 
{
	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()方法被调用了
	}
}

好了,看了结果后总结下吧

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

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

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

 

本文不是教会大家重写父类变量的,而是重点说明方法和变量的隐藏和覆盖,这些个小知识点虽然在做项目的时候不怎么会用到,但是一定要记住,不然的话很多错误会感到莫名其妙,还有就是SCJP的题库里这类题大大存在,所以本人觉得这些细小的知识还是记住为好



关于方法隐藏和覆盖的,

"重写覆盖"只能适用于实例方法.不能用于静态方法.对于静态方法,只能隐藏,重载,继承。要提到RTTI(run-time type identification)(运行期类型检查),也就是运行期的多态,当一个父类引用指向子类对象的时候

 专业术语有严格的含义,用语要准确."重写"只能适用于实例方法.不能用于静态方法.对于静态方法,只能隐藏(楼下说的可以重写那只是形式上的 ,并不满足多态的特征,所以严格说不是重写),重载,继承.
转载至:http://renyanwei.iteye.com/blog/258304

                
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值