【问题标题】:Hiding Super Class Methods from User of Child Class对子类的用户隐藏超类方法
【发布时间】:2017-07-22 18:34:59
【问题描述】:

我想知道是否可以防止用户在使用子类时调用父类的方法。同时,我希望这些方法对子类本身的方法可用。

例如,假设我有一个链表的实现。然后我通过继承(不确定它是否是好的设计......)基于它实现堆栈 ADT。因此,我希望对 Stack 类的用户“隐藏” LinkedList 类的方法。

链表:

class LinkedList(object):
    class Node(object):
        """
        Inner class of LinkedList. Contains a blueprint for a node of the LinkedList
        """
        def __init__(self, v, n=None):
            """
            Initializes a List node with payload v and link n
            """
            self.value=v
            self.next=n

    def __init__(self):
        """
        Initializes a LinkedList and sets list head to None
        """
        self.head=None

    def insert(self, v):
        """
        Adds an item with payload v to beginning of the list
        in O(1) time 
        """
        Node = self.Node(v, self.head)
        self.head = Node
        print("Added item: ", Node.value, "self.head: ", self.head.value)

    def size(self):
        """
        Returns the current size of the list. O(n), linear time
        """
        current = self.head
        count = 0
        while current:
            count += 1
            current = current.next
        return count

    def search(self, v):
        """
        Searches the list for a node with payload v. Returns the node object or None if not found. Time complexity is O(n) in worst case.
        """
        current = self.head
        found = False
        while current and not found:
            if current.value == v:
                found = True
            else:
                current = current.next
        if not current:
            return None
        return current

    def delete(self, v):
        """
        Searches the list for a node with payload v. Returns the node object or None if not found. Time complexity is O(n) in worst case.
        """
        current = self.head
        previous = None
        found = False
        while current and not found:
            if current.value == v:
                found = True
            else:
                previous = current
                current = current.next
        # nothing found, return None
        if not current:
            return None
        # the case where first item is being deleted
        if not previous:
            self.head = current.next
        # item from inside of the list is being deleted    
        else:
            previous.next = current.next

        return current

    def __str__(self):
        """
        Prints the current list in the form of a Python list            
        """
        current = self.head
        toPrint = []
        while current != None:
            toPrint.append(current.value)
            current = current.next
        return str(toPrint)

堆栈:

from PythonADT.lists import LinkedList

class Stack(LinkedList):
    def __init__(self):
        LinkedList.__init__(self)

【问题讨论】:

  • 不,这可能不是一个好的设计。如果不想暴露相同的接口,compose 不要inherit
  • 如果 Stack 不能履行 LinkedList 的接口承诺,它不应该扩展 LinkedList。
  • 如官方 Python 文档 "9.6. Private Variables" 中所述,可以在 class 中保护方法。只需通过以两个下划线开头的命名来声明该函数(例如:__private_search(self):)。
  • @jonrsharpe 你是在建议这样的事情吗? class Stack(object): def __init__(self): self.items = LinkedList() 之后我将继续实现 Stack ADT,但在幕后使用 LinkedList。
  • 是的,就是这样。或self._items 表示列表本身也不属于堆栈的公共接口。

标签: python python-2.7 python-3.x oop inheritance


【解决方案1】:

这是在类中声明受保护和私有方法的官方语法。

  1. 父类中声明的受保护方法可以从子类调用。
  2. 父类中声明的私有方法将对子类隐藏。

引发的异常是:

# AttributeError: '<ChildClass>' object has no attribute '__<private_function>'

第 1 步 - 在 class Parent 中声明私有方法和受保护方法。

class Parent(object):
    # a private method starts by 2 '_'
    def __parent_private(self):
        print('inside __parent_private()')

    # a protected method starts by 1 '_'
    def _parent_protected(self):
        print('inside _parent_protected()')

第 2 步 - 声明函数以从 class Child 调用这两个函数。

class Child(Parent):

    def call__parent_private(self):
        self.__parent_private()

    def call_parent_protected(self):
        self._parent_protected()

第 3 步 - 创建class Child 的实例以检查私有访问和受保护访问。

myChild = Child()

从子 1234562 检查受保护的方法 ==> 允许访问

# internal access of protected method
myChild.call_parent_protected()

输出:“inside _parent_protected()

# direct access of protected method
myChild._parent_protected()

输出:“inside _parent_protected()

从子 1234562 检查私有方法 ==> 访问被拒绝

# internal access of private method
myChild.call__parent_private()

错误:“AttributeError: 'Child' object has no attribute '_Child__parent_private'

# direct access of private method
myChild.__parent_private()

错误:“AttributeError: 'Child' object has no attribute '__parent_private'

【讨论】:

    猜你喜欢
    • 2011-11-17
    • 2011-08-15
    • 2016-04-13
    • 1970-01-01
    • 2014-12-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多