我正在使用python 3.6。 我的目标是创建一个能够以某种方式通过多态访问的基类 - 一个子类变量。 我知道这听起来有点'不是oop',所以如果用python无法完成我的描述 - 我想知道这个案例的最佳做法是什么。
按照维基百科的例子:
int wins = 0;
if (num1 == a1 || num1 == a2 || num1 == a3)
wins++;
if (num2 == a1 || num2 == a2 || num2 == a3)
wins++;
if (num3 == a1 || num3 == a2 || num3 == a3)
wins++;
if(wins == 3)
if(num1 == a1 && num2==a2 && num3==a3)
System.out.println("YOU'RE A MILLIONAIRE!");
else
System.out.println("You win 1,000 dollars!");
else if (wins == 2)
System.out.println("You win 100 dollars!");
else if (wins == 1)
System.out.println("You win 10 dollars!");
else
System.out.println("You lose!");
打印以下内容:
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()
我想实现完全相同的输出 - 使用
变量重载(是一个东西?)而不是方法重载。
原因是,在我正在处理的程序中 - Missy: Meow!
Mr. Mistoffelees: Meow!
Lassie: Woof! Woof!
,dog
和其他所有cat
将animal
完全相同的方式 - 仅受数据成员的影响,例如:
talk
打印以下内容:
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
self.vocabulary = [] # so called abstract data member
def talk(self): # Non Abstract method, all animals would talk
for word in self.vocabulary: print (word)
class Cat(Animal):
vocabulary = ["Meow", "Muuuew", "Maow"]
class Dog(Animal):
vocabulary = ["Woof", "Waf", "Haw"]
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print animal.name + ': ' + animal.talk()
显然,这不起作用,因为词汇表将是空的,因为它在基类中。
我尝试使用Missy: Meow Muuuew Maow
Mr. Mistoffelees: Meow Muuuew Maow
Lassie: Woof Waf Haw
找到解决方案,例如:
super
但结果将是class Cat(Animal):
vocabulary = ["Meow", "Muuuew", "Maow"]
def talk(self):
super(Animal,Cat).talk()
我使用AttributeError: 'super' object has no attribute 'talk'
错了吗?
答案 0 :(得分:0)
Python是动态类型的。没有必要以某种方式声明一个"抽象数据成员"在Animal
Animal
方法中引用self.vocabulary
;实际上,您试图声明一个"抽象数据成员"导致你的问题。
只需删除self.vocabulary = []
,talk
会在尝试访问vocabulary
时自动找到子类self.vocabulary
。
答案 1 :(得分:0)
您的代码中存在一些未解决的问题,但由于python是如此动态,它将通过正常查找找到子类实例属性:
class Animal:
def __init__(self, name):
self.name = name
def talk(self):
for word in self.vocabulary: print (word)
class Cat(Animal):
def __init__(self, name):
super().__init__(name)
self.vocabulary = ["Meow", "Muuuew", "Maow"]
class Dog(Animal):
def __init__(self, name):
super().__init__(name)
self.vocabulary = ["Woof", "Waf", "Haw"]
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print(animal.name, end=': ')
animal.talk()
如果您希望在代码中更明确地强制执行此要求,可以将Animal
作为抽象基类并创建名为vocabulary
的abstruct属性:
import abc
class Animal(abc.ABC):
def __init__(self, name):
self.name = name
@property
@abc.abstractmethod
def vocabulary(self):
...
def talk(self):
for word in self.vocabulary: print (word)
class Cat(Animal):
@property
def vocabulary(self):
return ["Meow", "Muuuew", "Maow"]