# 面向对象
# 类的定义
'''
基本形式：
class ClassName(object):
               Statement
	
    1.class定义类的关键字
    2.ClassName类名，类名的每个单词的首字母大写。
    3.object是父类名，object是一切类的基类。在python3中如果继承类是基类可以省略不写。
'''
class Fruits:
    fruit = 'xxxxxxx'
    list1 = []
    def __init__(self,name,color='red',weight=90):
        self.name = name
        self._color= color
        self.__weight = weight
        self.list2 = []
    def eat(self):
        print('我是%s,啊，被吃掉了。。。' % self.name)
    def show(self):
        print('我的重量是：%s' % self.__weight)

class Apple(Fruits):
    def __init__(self,shape):
        Fruits.__init__(self,'MMMM',weight=1000)
        self.shape = shape
    def eat(self,xxxx):
        Fruits.eat (self)
        print('被吃掉了',xxxx)
    def show(self):
        super().show()
        print('哈哈哈哈哈')
        self.eat()

ap = Apple('圆的')
banana = Fruits('banana','yellow')
apple2 = Fruits('apple','green')
# 类的初始化
#   __init__
'''
定义类时，这种方法可以使类对象实例按某种特定的模式生产出来。

后面的参数中第一个参数我们约定俗成的为self参数名，
self代表的是在类实例化后这个实例对象本身。

初始化函数除了有self这个参数表示实例对象本身之外，
其他的参数的定义也遵循函数的必备参数和默认参数一样的原则，
必备参数就是在实例化是一定要传入的参数，
默认参数就是在定义时可以给这个参数一个初始值。
'''

# 类的实例化
'''
基本形式：实例对象名 = 类名（参数）

在实例化的过程中，self代表的就是这个实例对象自己。

实例化时会把类名后面接的参数传进去赋值给实例，
这样传进去的参数就成为了这个实例对象的属性。

实例化的过程遵循函数调用的原则。
在实例化时也必须个数和顺序与定义时相同（使用关键字参数可以改变传参的顺序）。
当初始化函数定义时使用了默认参数时，在实例化时默认参数可以不传参这时
这个实例对象就会使用默认的属性，如果传了参数进去则会改变这参数值，
使实例化对象的属性就为你传进来的这个参数。

isinstance(实例名，类名)
判断一个实例是不是这个类的实例。
'''
# 类和实例属性
'''
类属性
.类属性是可以直接通过“类名.属性名”来访问和修改。
.类属性是这个类的所有实例对象所共有的属性，
 任意一个实例对象都可以访问并修改这个属性（私有隐藏除外）。
.对类属性的修改，遵循基本数据类型的特性：列表可以直接修改，字符串不可以，
 所以当类属性是一个列表时，通过任意一个实例对象对其进行修改。
 但字符串类型的类属性不能通过实例对象对其进行修改。

实例属性
.在属性前面加了self标识的属性为实例的属性。
.在定义的时候用的self加属性名字的形式，在查看实例的属性时
 就是通过实例的名称+‘.’+属性名来访问实例属性。

方法属性
.定义属性方法的内容是函数，函数的第一个参数是self，代表实例本身。

一些说明：
.数据属性会覆盖同名的方法属性。减少冲突，可以方法使用动词，数据属性使用名词。
.数据属性可以被方法引用。
.一般，方法第一个参数被命名为self,，这仅仅是一个约定，
 self没有特殊含义，程序员遵循这个约定。
.查看类中的属性和实例属性可以调用__dict__方法返回属性组成的字典。
'''
# 私有变量和类本地变量。
'''
以一个下划线开头的命名（无论是函数，方法或数据成员），
都会被隐藏起来。但直接将命名完整的写下还是一样可以访问到。
单下划线只是隐藏了属性，但还是可以从外部访问和修改。
以两个下划线开头的命名，一样会被隐藏，只能在内部访问和修改，
不能在外部访问，因为它变成了“_类名__属性”的形式。
在外部只能通过这种形式才能访问和修改。
双下划线开头的属性就变成了私有变量，即使能改也不要在外部外部修改了。
私有变量的作用就是确保外部代码不能随意修改对象内部的状态。
'''
# 数据封装：
'''
.在类里面数据属性和行为用函数的形式封装起来，
 访问时直接调用，不需知道类里面具体的实现方法。
'''
# 继承：
'''
.在定义类时，可以从已有的类继承，
 被继承的类称为基类，新定义的类称为派生类。

.在类中找不到调用的属性时就搜索基类，
 如果基类是从别的类派生而来，这个规则会递归的应用上去。
 反过来不行。

.如果派生类中的属性与基类属性重名，那么派生类的属性会覆盖掉基类的属性。
 包括初始化函数。

.派生类在初始化函数中需要继承和修改初始化过程，
 使用’类名+__init__(arg)’来实现继承和私有特性,也可以使用super()函数。

issubclass(类名1，类名2)
判断类1是否继承了类2
'''
# 多态：
'''
.多态是基于继承的一个好处。

.当派生类重写了基类的方法时就实现了多态性。
'''