多态的实际示例

61 投票
3 回答
86310 浏览
提问于 2025-04-16 04:12

有没有人能给我一个现实生活中的多态性实际例子?我的教授总是给我讲那些老掉牙的故事,比如说+运算符。a+b = c2+2 = 4,所以这就是多态性。我真的无法和这样的定义产生联系,因为我在很多书里都读过这些。

我需要的是一个能让我真正理解的现实世界的例子,最好还有代码。

比如,这里有一个小例子,万一你想扩展一下。

>>> class Person(object):
    def __init__(self, name):
        self.name = name

>>> class Student(Person):
    def __init__(self, name, age):
        super(Student, self).__init__(name)
        self.age = age

3 个回答

6

上面回答中提到的一个C++多态性的例子是:

class Animal {
public:
  Animal(const std::string& name) : name_(name) {}
  virtual ~Animal() {}

  virtual std::string talk() = 0;
  std::string name_;
};

class Dog : public Animal {
public:
  virtual std::string talk() { return "woof!"; }
};  

class Cat : public Animal {
public:
  virtual std::string talk() { return "meow!"; }
};  

void main() {

  Cat c("Miffy");
  Dog d("Spot");

  // This shows typical inheritance and basic polymorphism, as the objects are typed by definition and cannot change types at runtime. 
  printf("%s says %s\n", c.name_.c_str(), c.talk().c_str());
  printf("%s says %s\n", d.name_.c_str(), d.talk().c_str());

  Animal* c2 = new Cat("Miffy"); // polymorph this animal pointer into a cat!
  Animal* d2 = new Dog("Spot");  // or a dog!

  // This shows full polymorphism as the types are only known at runtime,
  //   and the execution of the "talk" function has to be determined by
  //   the runtime type, not by the type definition, and can actually change 
  //   depending on runtime factors (user choice, for example).
  printf("%s says %s\n", c2->name_.c_str(), c2->talk().c_str());
  printf("%s says %s\n", d2->name_.c_str(), d2->talk().c_str());

  // This will not compile as Animal cannot be instanced with an undefined function
  Animal c;
  Animal* c = new Animal("amby");

  // This is fine, however
  Animal* a;  // hasn't been polymorphed yet, so okay.

}
12

在Python中,一个常见的实际例子就是类文件对象。除了真实的文件,还有几种其他类型的对象,比如StringIOBytesIO,它们也可以被看作是类文件对象。那些能够像文件一样操作的方法,也可以用在这些对象上,因为它们支持所需的方法(比如readwrite)。

168

看看维基百科的例子:它在高层次上非常有帮助:

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Cat('Mr. Mistoffelees'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

# prints the following:
#
# Missy: Meow!
# Mr. Mistoffelees: Meow!
# Lassie: Woof! Woof!

注意以下几点:所有动物都会“说话”,但它们的说话方式不同。因此,“说话”这种行为在这里是多态的,意思是它会根据不同的动物以不同的方式表现出来。所以,抽象的“动物”概念其实并不“说话”,而是具体的动物(比如狗和猫)有自己特定的“说话”实现。

同样,“加法”这个操作在很多数学对象中都有定义,但在特定情况下你会根据特定的规则来“加”:比如1+1=2,但(1+2i)+(2-9i)=(3-7i)。

多态行为让你可以在“抽象”的层面上定义共同的方法,然后在具体的实例中实现它们。

以你的例子为例:

class Person(object):
    def pay_bill(self):
        raise NotImplementedError

class Millionare(Person):
    def pay_bill(self):
        print "Here you go! Keep the change!"

class GradStudent(Person):
    def pay_bill(self):
        print "Can I owe you ten bucks or do the dishes?"

你看,百万富翁和研究生都是人。但在付账的时候,他们的具体“付账”方式就不同了。

撰写回答