class Liquid(object):
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
上記の 2 つのクラスがあるとします。 WaterはLiquidから継承します。Water が親のメソッドの 1 つを継承するのを制限する方法はありますbar()
か?
class Liquid(object):
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
上記の 2 つのクラスがあるとします。 WaterはLiquidから継承します。Water が親のメソッドの 1 つを継承するのを制限する方法はありますbar()
か?
並べ替え。しかし、それをしないでください。
class Liquid(object):
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
def __getattribute__(self, name):
if name == 'bar':
raise AttributeError("'Water' object has no attribute 'bar'")
l = Liquid()
l.bar()
w = Water()
w.bar()
メソッドをノーオペレーションにオーバーライドすることはできますが、削除することはできません。そうすることは、オブジェクト指向設計の中核となる原則の 1 つに違反することになります。つまり、親から継承するオブジェクトは、親が使用される場所ならどこでも使用できるようにする必要があります。これは、リスコフの置換原理として知られています。
他の答えのように、継承されたメソッドの 1 つを壊すことができます。
別の方法は、「オプションの」メソッドをリファクタリングし、それらを持たない基本クラスから継承することです。
class BaseLiquid(object):
def foo(self):
pass
class Barised(object):
def bar(self):
pass
class Liquid(BaseLiquid, Barised): pass
class Water(BaseLiquid):
def drip(self):
pass
これはおそらく良い考えではありませんが、いつでもメタクラスを使用してプライベート属性を実装できます。
def private_attrs(name, bases, attrs):
def get_base_attrs(base):
result = {}
for deeper_base in base.mro()[1:]:
result.update( get_base_attrs(deeper_base) )
priv = []
if "__private__" in base.__dict__:
priv = base.__private__
for attr in base.__dict__:
if attr not in priv:
result.update( {attr: base.__dict__[attr]} )
return result
final_attrs = {}
for base in bases:
final_attrs.update( get_base_attrs(base) )
final_attrs.update(attrs)
return type(name, (), final_attrs)
class Liquid(object):
__metaclass__ = private_attrs
__private__ = ['bar']
def foo(self):
pass
def bar(self):
pass
class Water(Liquid):
__metaclass__ = private_attrs
print Water.foo
print Water.bar
出力は次のとおりです。
<unbound method Water.foo>
Traceback (most recent call last):
File "testing-inheritance.py", line 41, in <module>
print Water.bar
AttributeError: type object 'Water' has no attribute 'bar'
編集:クラスのベースを変更しないため、これは isinstance() を台無しにします。
http://docs.python.org/release/2.5.2/ref/slots.html
スロット属性を使用して、これを行うことができると思います。
getattrメソッドを実装し、bar が呼び出された場合に適切な例外をスローすることが可能になる場合があります。
ただし、これは悪い設計の兆候であるため、実際にはこれを行いたくないことに同意します。