'''
OOP:面向对象程序设计(Object Oriented Programming)
继承:
    从父类(class)把一些特性(属性和方法),直接就给子类使用。
    是指新创建的类,从某个类中获取一些属性和方法(在新类中不需要自己再写一遍)
    父类(也叫基类):某个类就是父类或者基类

    子类(也叫派生类):新创建的类就是子类或者派生类

    重写:重写的对象是从父类继承过来的方法,因为父类的方法用在子类中不合适了,在子类中定义一个和父类重名的方法覆盖掉继承的父类的方法。

    子类现有的属性是父类继承来的,继承的父类的构造方法(默认就继承过来了,并且是不显示出来的)
    如果在子类中显示的写了构造方法:def __init__(self,xxx),其实就是覆盖了父类的构造方法了,就不使用父类的属性
    如果显示的写了构造方法,并且还希望使用父类的构造方法(在子类中添加特殊的属性,其他共有的属性还是要用父类),要求必须要显示的调用父类的构造方法:animal.__init__(self,xxx)
    类能直接调用方法的,但是实例方法(eat()、climb())是不能使用类名直接调用,只能使用对象来调用:
        c=cat(xxxx),c.eat()----有对象名
        cat(xxxx).eat()-----没有对象名,匿名对象(用的不频繁,用的次数少)
    类方法(也叫静态方法):是可以直接使用类来调用的,animal.__init__(self,xxx)

    对于父类中私有的成员属性,子类是不能直接继承的,可以通过父类提供访问接口获取数据
    对于父类的私有方法,一般不会定义私有的方法,意义不大。



'''


class animal():
    def __init__(self, name, age, color, weight):
        self.name = name
        self.age = age
        self.__color = color
        self.weight = weight

    def eat(self):
        print("动物在吃饭。")

    def __sleep(self):
        print("小动物在睡觉!")


class cat(animal):
    # 继承父类的属性

    # 重写eat()方法
    def eat(self):
        print("小猫在吃鱼。")

    # 小猫特有的方法
    def climb(self):
        print("小猫在爬树。")


class dog(animal):
    def __init__(self, name, age, color, weight, wangwang):
        # 调用父类的构造方法对前三个参数进行初始化
        animal.__init__(self, name, age, color, weight)
        self.wangwang = wangwang

    def eat(self):
        print("小狗在吃肉。")

    # 小狗特有的方法
    def Wang(self):
        print("小狗在%s。" % self.wangwang)


# 创建对象
c = cat('小花', 2, 'black', 12)
# c.sleep() AttributeError: 'cat' object has no attribute 'sleep'
c.eat()
c.climb()

 



d = dog("小黑", 3, 'black', 12, "旺旺")
# print(d.__color)  AttributeError: 'dog' object has no attribute '__color'
d.eat()
d.Wang()
'''
多态:

注意:
    1、多态的前提是继承
    2、python中的多态效果并不是很明显
    3、叫做鸭子多态,并不要求严格的继承体系
'''