OOP 面向对象编程 Object Oriented Programming
我自己的理解:面向对象就是把是柏拉图的2个世界
1: 编程世界中,类现实世界,有数据和函数等做成的,XX物体,XX对象,拟真
2:纯粹抽象世界,这里都是原型的,抽象的形状/物体,理想世界
(1) 最核心的概念,是对数据进行抽象---变成对象object
然后把过程作为数据的方法,都包在对象内 obj.method。
(2) 最重要,最基础的概念的是 class类。
类的实例,class 和 instance (new 一个instance--obj出来)
(3) 和函数式编程不同的是
函数式编程,是把过程抽象,只要函数,参数在函数之间传递,不要数据。
只有抽象的过程--函数
数据---函数的参数
数据类型和对象
所有的数据类型都是对象:
一切都是数据类型,包括 函数,类都是数据类型,是自定义数据类型!!
obj:int float,str, list tuple set dict
其他数据对象
obj: func ,class,
而且,class某种意义上 == dict
dict={"num":229,"floor":3}
>>> class Class():
def __init__(self):
self.num=229
self.floor=3
def print_class(self):
print(self.num,self.floor)
>>> class1=Class()
>>> class1.print_class()
229 3
CLASS 类
类是一个模板(本质也可以认为是 函数,或者 字典?)
定义类
(1)语法(函数必须带(),而类class可以不带())
- class 关键字
- 类名:最好第一个字母大写
- () :可有,可没有
class Test_class1()
class Test_class1 #因为默认继承object类,所以有无括号都行
class Test_class1(object) #标准写法,除非要继承其他类
(2)class包含内容---无法直接访问的属性,都可以写方法让外部获得和修改
- 属性 attribute:属于一个对象的变量 var 就称为 attribute
特殊属性 (特殊变量)
__name__
CLASS的绝对私有变量?
attri1 (不带self也是私有的吧?完全无法访问吧?)
CLASS的 私有属性(私有变量):只有class内部才可以直接访问
self. __attri2 == _Class__name
例子:instance1._Class__name (class前面1个下划线,后面name是2个下划线)
classs最好私有变量:可以被外部 直接访问,但最好当做私有变量
self. _attri2
普通属性( 实例变量) (可继承属性)
self.attri3
>>> class Cat():
def __init__(self):
self.name="mimi"
self._nation="uk"
self.__location="london"
>>> cat101=Cat()
>>> cat101.name
'mimi'
>>> cat101._nation
'uk'
>>> cat101.__location
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
cat101.__location
AttributeError: 'Cat' object has no attribute '__location'
>>> cat101._Cat__location
'london'
>>>
>>> cat101.color #完全无法访问吧?
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
cat101.color
AttributeError: 'Cat' object has no attribute 'color'
- 方法 method:属于一个对象的函数 func 就称为 method
类的每个实例方法(有其他方法),第一个参数,永远是self,并且在被实例化后调用时不需要传递self这个参数
#如果class内的method不带self,那么类的实例就无法调用这个方法
- 方法类型
- __init__()方法 (不能加return???)
可以没有这个方法,但是,只有这个方法,定义了class的基础内容
instance 必然有 __init__()里面的内容,而class的其他内容调用才行
实例化class时,必须带__init__()方法的参数(不需要写self)‘
- 实例方法 ,必带(self) 参数
- 类方法
- 静态方法
>>> class Test_class1():
def __init__(self):
self.num=229
self.floor=3
def print_class(self):
print(self.num,self.floor)
def static_method1():
return 999
def class_method1(cls):
return cls.__cla__val
父类和子类
父类:base class / super class
子类:subclass
子类的属性和方法
- 子类调用了自己没有的类型,会往上去查找
- 子类天然拥有父类的__init__()的内容?
因为会往上去查找
好像必须写
- 属性也可以覆盖,新加
- 方法也可以重写,新加
instance 实例 (就是object吧)
实例化
类class是无法被调用的,必须先实例化,然后才能用class的属性和方法
实例化的本质:在class里调用 __init(self)__函数,就是 __init__(instance1),instance代替了self
调用
调用方法的原理
对象调用方法时, 实际上是通过类调用的
a = Test_class()
a.method()
实际上是这样调用的 Test_class.method(a)
这样self 就是 a, python隐含地把a 传进方法 替代了self, 就成了绑定的方法, 就可以执行了. 否则就是非绑定方法
A 实例化调用:两种方法--都需要带括号
1 从内置类实例化
instan1=sprite.Sprite() #调用的是__init__()方法的内容
2 从自定义的类实例化
class Test_class1()
instan1=Test_class1() #调用的是__init__()方法的内容
B 类名赋值----如果不带括号!!!
varA=Test_class2
varA() 其实是类,而不是实例
>>> class class_test1:
a=99
def __init__(self):
self.a=100
>>> new1=class.test1()
SyntaxError: invalid syntax
>>> new1=class_test1()
>>> new1.a
100
>>> new2=class_test1
>>> new2.a
99
>>> new1.b=500
>>>
参考文档:
python中的那些坑
https://www.cnblogs.com/ywhyme/p/6913057.html
instance 实例的内容(实际上没有内容,都是 继承得来,类的属性和方法)
- 属性 attribute:属于一个对象的变量 var 就称为 attribute
特殊属性 __name__
私有属性 __attri1
普通属性( 实例属性) self.attri2
- 方法 method:属于一个对象的函数 func 就称为 attribute
- 除了继承的属性
- instance还可以自己定义,额外的属性,和类。但只对自己生效。
isintance()
#这个函数,是不是可以理解为,一切obj都是实例化出来的,都是源自obj 这个base class?
isinstance(object, classinfo)
isinstance() 与 type() 区别:
-
type() 不会认为子类是一种父类类型,不考虑继承关系。
-
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
实际例子: 父类,子类和实例化
>>> class Animal():
def __init__(self,name):
self.name=name
def run(self):
print("%s is running" %(self.name))
# 实验得,实例化子类时,只需要传入 子类.方法 需要的参数就可以了
# 写法多种
前提:子类的方法run(self ,name )里需要用到name
写法1 子类里,自己init了一个 self.name,用于自己的实例(父类里可以有,也可以没有)
写法2:若在子类里完全不写,就会往上去找父类的
错误:不写self.的 属性和方法,将无法被实例的对象继承或者调用到!
>>> class CatM(Animal): #子类的init 继承父类的,同时自己定义self.name 覆盖了父类的?
def __init__(self,name):
Animal.__init__(self,name)
self.name=name
def run(self):
print("%s is running" %(self.name))
>>> cat102=CatM("haha")
>>> cat102.run()
haha is running
>>> class CatN(Animal): #子类的init 继承父类的,不知道有没有用?
def __init__(self,name):
Animal.__init__(self,name)
def run(self):
print("%s is running" %(self.name))
>>> cat103=CatN("heihei")
>>> cat103.run()
heihei is running
>>> class Cat(Animal): #只但在子类里写
def __init__(self,name):
self.name=name
def run(self):
print("%s is running" %(self.name))
>>> cat101=Cat("mimi")
>>> cat101.run()
mimi is running
>>> class CatP(Animal): #子类里完全不定义name
def run(self):
print("%s is running" %(self.name))
>>> cat104=CatP("gogo")
>>> cat104.run()
gogo is running
新的试验例子---故意让子类缺少父类的参数
(1)正确写法:需要继承父类的__init__()方法
>>> class Dog(Animal):
def __init__(self,name):
self.name=name
def run(self):
print("%s \'s animal %s is running" %(self.nation,self.name))
>>> class Dog(Animal):
def __init__(self,nation,name):
Animal.__init__(self,nation)
self.name=name
def run(self):
print("%s \'s animal %s is running" %(self.nation,self.name))
>>> dog103=Dog("JP","jack")
>>> dog103.run()
JP 's animal jack is running
(2)错误写法:子类里找不到nation 也不知道从哪儿去找
>>> class Dog(Animal):
def __init__(self,name):
Animal.__init__(self,nation)
self.name=name
def run(self):
print("%s \'s animal %s is running" %(self.nation,self.name))
>>> dog102=Dog("jack)
Traceback (most recent call last):
File "<pyshell#125>", line 1, in <module>
dog102=Dog("jack")
File "<pyshell#124>", line 3, in __init__
Animal.__init__(self,nation)
NameError: name 'nation' is not defined