Java继承问题以及子类转换为父类时调用方法及属性的情况

1.方法的继承

子类可以继承父类的非private方法。

class parent{
	public void pnp() {
		System.out.println("Parent");
	}
}
class child extends parent{

}
child c = new child();
c.pnp();

输出结果为Parent.

 

子类可以重写父类的非private方法。

class parent{
	public void pnp() {
		System.out.println("Parent");
	}
}
class child extends parent{
	@Override
	public void pnp() {
		System.out.println("Child");
	}
}

这时,输出结果为Child

 

对于父类的private方法,子类是不可见的,尝试调用父类的private方法会导致静态检查直接报错。

 

当然,子类中也可以添加自己独特的新方法。如果子类中写了一个和父类某个private方法一样的方法,这不能算重写,应该也算添加新方法。

2.属性的继承

属性的继承和方法的继承类似,子类可以继承父类的非private属性。父子类定义如下:

class parent{
	int np = 0;
}
class child extends parent{
	
}

子类child可以访问np属性,在main中进行测试,输出结果为0.

child ch = new child();
System.out.println(ch.np);

 

当然,类似于方法的重写,子类也可以覆盖掉父类的属性。

class parent{
	int np = 0;
}
class child extends parent{
	int np = 1;
}

测试代码和上面一样,输出结果为1.

 

当子类试图访问父类的private属性时,静态检查会直接报错。

 

子类中也可以添加自己独特的新属性。

3.方法与属性混合的情况

如果方法是从父类继承的,那么方法中使用到的属性都是父类的属性。

class parent{
	int np = 0;
	public void pnp() {
		System.out.println(np);
	}
}
class child extends parent{
	int np = 1;
}
child ch = new child();
ch.pnp();

在main中测试,输出结果是0.即使子类中已经覆盖了属性np,但是方法的行为仍然和父类一致,这时就不能简单地看代码的逻辑了。如果子类想按照代码的逻辑实现功能的话就只能重写,而重写的代码和之前一模一样。

class parent{
	int np = 0;
	public void pnp() {
		System.out.println(np);
	}
}
class child extends parent{
	int np = 1;
	@Override
	public void pnp() {
		System.out.println(np);
	}
}

这时测试输出结果为1.

 

然而对于方法内部再次调用方法的情况,却正好相反。如果从父类继承来的方法A调用了方法B,并且子类重写了方法B,当子类调用方法A时,方法A内部会调用被重写的方法B.

class parent{
	public void A() {
		B();
	}
	public void B() {
		System.out.println("Origin");
	}
}
class child extends parent{
	public void B() {
		System.out.println("Override");
	}
}

子类调用A()时会输出Override。

4.子类转换为父类时,调用方法及属性的情况

显然的是,当子类转换为父类后,只能调用父类中存在的方法、访问父类中存在的属性。

当访问属性时,属性的值是父类中的值。

class parent{
	int np = 0;
}
class child extends parent{
	int np = 1;
}
parent c = new child();
System.out.println(c.np);

输出结果为0.

 

而调用的方法应该是子类中的方法。

如果方法被重写,调用的方法就是子类中被重写的方法。

class parent{
	public void A() {
		System.out.println("Origin");
	}
}
class child extends parent{
	@Override
	public void A() {
		System.out.println("Override");
	}
}
parent c = new child();
c.A();

输出结果为Override。

如果方法没有被重写,调用的方法就是父类中的方法。

class parent{
	public void A() {
		System.out.println("Origin");
	}
}
class child extends parent{
	
}
parent c = new child();
c.A();

输出结果为Origin。

如果调用的方法中访问了某个属性或者又调用了其他方法时,会遵循3中给出的分析。

简单总结一下

对于属性的访问,在运行前就会确定,因此只看当前的类型,当前的类型是什么就访问这个类型中定义的属性;而对方法的调用在运行时才会确定,要看原本的类型(即new的时候的类型),按照这个类型调用相应方法。而方法内部如果访问了属性,这个属性是定义该方法的那个类型中的属性;方法内部如果调用了其他方法,被调用的方法仍然是这个类型中的方法,当然,也存在嵌套的情况。

 

 

 

 

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值