我了解了java中的多态性,当(子)扩展类中的方法将覆盖父类中的方法时,方法何时会重载其他方法。
这个网站帮助我理解了这些问题。 但是,我没有找到任何解释什么以及如何转换对象,和/或转换传递给方法的参数会影响方法覆盖和重载。
铸造和重载的一个例子:
public class A{
private int num;
public A(int n){
num = n;
}
public int getNum(){
return num;
}
public boolean f(A a){
return num == a.num * 2;
}
}
public class B extends A {
public B(int n){
super(n);
}
public boolean f(B b){
return getNum() == b.getNum();
}
}
public class C extends A {
public C(int n){
super(n);
}
public boolean f(A a){
return a instanceof C && getNum() == a.getNum();
}
}
构造这行代码:
A y1 = new B(10);
C z2 = new C(10);
System.out.println(z2.f((C)y1));
如何影响y1的演员阵容? 我对一般的想法感兴趣...铸造如何影响重载和覆盖?
答案 0 :(得分:1)
类型转换会将引用从一种类型更改为另一种类型
重载是指具有相同名称的2个函数接受不同的参数,并且基于参数执行正确的函数
覆盖是指子类的方法从其基类替换或覆盖相同的方法
我没有看到什么铸件与覆盖或重载
有关答案 1 :(得分:1)
转换对象不会影响调用重写方法的方式,这意味着对f(A)
的调用不会受到影响。
但是,它们仍然可以影响实际使用的重载方法。请注意,班级f(B)
中的B
并未真正覆盖f(A)
。相反,它是方法的重载:
public class B extends A {
//...
public boolean f(B b) {... } // implements function accepting a B reference argument
// since it extends A, this method also exists, and is implemented by class A:
//public boolean f(A a);
}
例如,如果您要将y1
转换为B
,则会改为调用方法f(B)
。
A y1 = new B(10);
B z2 = new B(10);
System.out.println(z2.f(y1); // calls z2.f(A), implemented by class A
System.out.println(z2.f((B)y1)); // calls z2.f(B)
这是因为引用类型随着强制转换而更改,然后转换与可能不同的方法签名相关联。
答案 2 :(得分:1)
首先,您的代码示例将无法运行,因为A
,y1
的实例无法转换为C
。
那就是说我想你所问的是引用类型如何影响被调用的方法。
第一个重点是 Java在方法重载时使用静态绑定。
Java中的静态绑定与引用类型一起使用,可以通过强制转换来改变,因此给出了原因:
A
扩展B
B
和A
public void f(A a)
和public void f(B b)
会发生这种情况:
A a = new B();
B b = new B();
f(a); //calls f(A a)
f(b); //calls f(B b)
f((B)a); //calls f(B b)
下一个重点是 Java在覆盖方法时使用动态绑定。
Java中的动态绑定适用于实例类型,因此给出了原因:
C
public void f(String s)
D
的类C
并覆盖方法public void f(String s)
会发生这种情况:
C c = new C();
D d = new D();
c.f("hello"); //calls C.f(String s)
d.f("hello"); //calls D.f(String s)
((C)d).f("hello"); //calls D.f(String s)
答案 3 :(得分:1)
可能你会对TypeCasting&多态性。我在你的代码中看到的另一个坏处是你将一个子类转换为另一个子类。永远记住,子类之间的TypeCasting是不可能的。
如果方法的形式参数定义了SuperClass参考&您将ConcreteClass引用作为实际参数传递,然后将其称为扩展,这不需要进行类型转换。但是,如果方法的正式参数定义了ConcreteClass参考&您将SuperClass引用作为实际参数传递,然后将其称为缩小&你必须明确地进行类型转换。
Typecasting&多态性是不同的故事。以下是我见过的多态性最好的例子。
public class Character {
private Weapon weapon;
public static void main(String[] args) {
Character hero = new Character();
Sword s1 = new Sword();
Weapon s2 = new Sword();
//s1 = s2; Weapon isn't Sword
s1 = (Sword)s2; //Narrowing
hero.setWeapon(s1);
hero.performAttack();
hero.setWeapon(new ShotGun());
hero.performAttack();
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public void performAttack(){
weapon.performAttack();
}
}
interface Weapon {
public void performAttack();
}
class Sword implements Weapon {
@Override
public void performAttack() {
System.out.println("Slashing enemies");
}
}
class ShotGun implements Weapon {
@Override
public void performAttack() {
System.out.println("Shooting enemies");
}
}