Inheritance 理解遗传和多态性

Inheritance 理解遗传和多态性,inheritance,polymorphism,Inheritance,Polymorphism,我的问题是关于继承和多态性 我有一个班,是超级班。类B和C扩展了A,是子类 现在我在另一个类(不是a、B或C)中有一个函数,它的参数类型为a。因此多态性允许我们将参数作为A、B或C传递给该函数。现在在该函数中,为了访问B的属性,我必须将收到的参数类型转换为B 类型转换是一种好的编程技术吗?如果没有,多态性在这里有什么用途 谢谢。只有当你知道如何进行类型转换时,类型转换才有用 这里多态性的用途是,另一个类中的方法可以用通用的方式编写,因此一段代码可以在不同的类型上操作,尽管这些类型有一些共同的接口

我的问题是关于继承和多态性

我有一个班,是超级班。类BC扩展了A,是子类

现在我在另一个类(不是a、B或C)中有一个函数,它的参数类型为a。因此多态性允许我们将参数作为ABC传递给该函数。现在在该函数中,为了访问B的属性,我必须将收到的参数类型转换为B

类型转换是一种好的编程技术吗?如果没有,多态性在这里有什么用途


谢谢。

只有当你知道如何进行类型转换时,类型转换才有用

这里多态性的用途是,另一个类中的方法可以用通用的方式编写,因此一段代码可以在不同的类型上操作,尽管这些类型有一些共同的接口(类a)

所以。。。打字(取决于语言文化)是一种非常糟糕的做法。首选使用多态性(取决于…),例如使用签名创建不同的方法
->(B)
,使用类型为B的参数

更新:添加Java伪代码

class A { int m() {} }
class B extends A { int b() {} }
class C extends A {}
class $ { 
  static void x(A $$) {} 
  static void x(B $$) {}
}
public class P {
  public static void main(String[] a) {
    $.x(new A()); //calls $::x(A)
    $.x(new B()); //calls $::x(B)
  }
}

我假设您想要这样的东西(伪代码):

在这种情况下,您需要进行类型转换:

void foo(A obj) {
    if (obj.isOfClass(B)) {
        ((B)obj).propertyOfB();
    }
}
根据语言的不同,还有另一种方法。在Ruby和Objective-C这样的语言中,通常使用所谓的方法来代替检查对象是否属于特定类型。这个想法是:如果它像鸭子一样走路,像鸭子一样嘎嘎叫,那么它一定是鸭子。换句话说,在这里,对象的类型并不重要,重要的是它是否实现了某些方法:


频繁使用duck类型的语言通常更具“动态”性质。例如,C++中,它是非常严格的类型系统,几乎不可能做鸭式输入(AFAIK),而在上述Ruby和Objul-C./P>中,它非常自然,其好处是代码重用和提供不同的行为。这就是为什么它被称为多态性。你的意思是,在你的方法中,你想要一个类型为A的对象(以及它的子类),但是如果对象恰好是类型B的,你想要访问特定于B的属性(即,在A中不可用的),这就是我要找的。你可能想把访问者或策略模式作为检查类、强制转换和使用if语句处理不同类的替代方法。那么,如果我在参数上使用instanceof运算符,如果它是类型B,则将其强制转换为B是否好?是的,这应该是安全的,但是为了清晰/美观,最好使用单独的方法。如果我创建了一个签名为B的不同方法,那么无论我在哪里调用该方法,我都需要检查参数的类型并相应地调用该方法。这不是更复杂吗?不,语言会自动为你做这件事!这就是多态性的全部要点,您可以有具有相同标识符(名称)但不同签名(参数类型)的方法,并且自动调用正确的方法,即使一种类型包含另一种类型(选择较窄的类型)。。。至少,在任何合适的编程语言中,它都是这样工作的。明白了。谢谢,但是如果我有两种方法,我不是在第二种方法中添加了一点额外的信息来复制代码吗?我使用的是java。我猜打字是唯一的方法?同样,类型转换是一种好的编程技术吗?在Java中,类型转换是唯一的方法。它的风格是否好取决于用例。如果用在思考上,很少用,那也没什么大不了的。但是,如果您注意到您正在一次又一次地转换,您可能应该重新考虑您的类层次结构,或者如何以不同的方式(接口)抽象事物。
void foo(A obj) {
    if (obj.isOfClass(B)) {
        ((B)obj).propertyOfB();
    }
}
void foo(Object obj) {
    if (obj.hasMethod(quack)) {
        obj.quack();
    }
}