面向对象(Object Oriented)

面向对象技术简介

  • 类(class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 方法:类中定义的函数。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量:定义在方法中的变量,只作用于当前实例的类。
  • 继承:即一个派生类(derivedclass)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

类是具有相同属性和技能的一类事物,如:人类的通性,即每个人都具有的

语法:

class Objectname:
    """
    注释
    """
    variable_name = variable_value  # 这里的变量是该类线所有成员都具有的,通用的
                              # 这里的变量称为静态变量或静态字段
    def __init__(self):
        pass
    def functuion(self):
        pass
    

类名的查看和调用:
1.类名查看类中所有的变量(字段),方法(函数):

Objectname.dict

2.类名对静态变量(静态字段)进行操作 最好不要通过__dict__这个字典进行操作
2.1通过类名.dict 不建议!!!通过这个方法

1.查询类里面所有的变量 Person.dict
2.(增删改)查询单个变量 不要用Person.dict

2.2 通过类名.变量名 常用!!!
3.类名对动态方法(函数)进行操作
3.1 通过类名.dict 不建议!!!通过这个方法
3.2 类名.方法名

class Person:
    '''
    此类是构建人类
    '''
    level = '高级动物'
    mind = '有思想'
    language = '语言'

    def __init__(self):
        pass
    def work(self):
        print('开始工作了!!!!')
    def eat(self):
        pass
# print(Person.__dict__['mind']) # 可以查值
# Person.__dict__['create'] = '有创造力' #  不能增加值
# del Person.__dict__['mind']  # 不能删除值
# Person.__dict__['mind'] = '行尸走肉'  # 不能更改值
# print(Person.__dict__)

# print(Person.mind)  # 可查询
# print(Person.language)  #可查询
# Person.create = '有创造力' # 可增加
# del Person.mind # 可删除
# Person.mind = '行尸走肉'
# print(Person.mind)
# print(Person.__dict__)

# Person.work(111)

类对象

类对象支持两种操作:属性引用和实例化。
属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name。
类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:

class MyClass:
    """一个简单的类实例"""
    i = 12345
    def f(self):
        return 'hello world'
 
# 实例化类
x = MyClass()   # x是抽象的对象, MyClass()是实例化
 
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())

以上创建了一个新的类实例并将该对象赋给局部变量x,x为空的对象。执行以上程序输出结果为

MyClass 类的属性 i 为: 12345
MyClass 类的方法 f 输出为: hello world

很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为__init__()的特殊方法(构造方法),像下面这样:

def __init__(self):
    self.data = []

类定义了 init() 方法的话,类的实例化操作会自动调用__init__()方法。所以在下例中,可以这样创建一个新的实例

x = MyClass()

当然, init() 方法可以有参数,参数通过__init__()传递到类的实例化操作上。例如:

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i)   # 输出结果:3.0 -4.5

self代表类的实例,而非类
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是 self。
self是对象的空间地址

class Test:
    def prt(self):
        print(self)
        print(self.__class__)
 
t = Test()
t.prt()

以上实例执行结果为:

<__main__.Test instance at 0x100771878>
__main__.Test

从执行结果可以很明显的看出,self代表的是类的实例,代表当前对象的地址,而self.class 则指向类。
self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的:

class Test:
    def prt(runoob):
        print(runoob)
        print(runoob.__class__)
 
t = Test()
t.prt()

以上实例执行结果为:

<__main__.Test instance at 0x100771878>
__main__.Test

类的方法

在类地内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))
 
# 实例化类
p = people('runoob',10,30)
p.speak()

执行以上程序输出结果为:

runoob 说: 我 10 岁。

实例化对象

用下面一段代码

class Person:
    '''
    此类是构建人类
    '''
    level = '高级动物'
    mind = '有思想'
    language = '语言'

    def __init__(self,name,age,sex,area,hobby):  # 构造方法
        self.name = name  # slef.name name 是对象属性
        self.age = age
        self.sex = sex
        self.area = area
        self.hobby = hobby

    def work(self,eye):
        self.eye = eye
        print('开始工作了!!!!')
    def eat(self):
        pass
        
aduan = Person('啊段',18,'男','河北邯郸','非女')

aduan = Person('啊段',18,'男','河北邯郸','非女') 这个过程叫做实例化对象
对象相对于其他的对象具有个性,这个个性化的过程就是实例化对象
1,产生一个对象空间,包含内的指针,返回给self空间内存地址
2,自动执行类中的__init__方法,并将空的对象空间传给self,剩下的值传给相应形参
3,执行init方法,给对象封装属性,并将完善好的这个对象返回给 类名()

对象的属性:
1,查找对象中的所有属性
2,对象操作对象中属性.
3,对象操作类中的静态变量(静态字段). 只能查询不能增删改.

    # 1,查找对象中的所有属性
# aduan = Person('啊段',18,'男','河北邯郸','非女')
# print(aduan.__dict__)

# aduan = Person('啊段',18,'男','河北邯郸','非女')
# aying = Person('啊颖',17,'女','河北衡水','开车...')
    #2, 对象操作对象中属性.
# aduan = Person('啊段',18,'男','河北邯郸','非女')
# print(aduan.name) # 查
# aduan.job = 'student' # 增
# del aduan.age # 删
# aduan.sex = 'laddyboy'
# print(aduan.__dict__)
    #3,对象操作类中的静态变量(静态字段). 只能查询不能增删改.
# aduan = Person('啊段',18,'男','河北邯郸','非女')
# print(aduan.level)  # 查 类中的静态字段
# aduan.level = '中等动物'  # 对象中设置新属性,而不是改变类中的level
# print(aduan.level)
# del aduan.level
# print(Person.__dict__)

4.对象执行类中的方法

aying = Person('啊颖',17,'女','河北衡水','开车...')
print(aying)
aying.work('大眼睛')
print(aying.__dict__)
# 1 self 位置参数, 默认接受的是对象空间,约定俗成叫self.
# 2 在类的非__init__方法中,也可以给对象添加一些属性,前提必须先执行这个方法.

类的名称空间,对象名称空间
类的名称空间:在执行类是,在内存空间中创建一个存放类的内存空间
对象名称空间:在实例化对象过程中,会在内存空间中创建一个存放对象属性的内存空间,和类的名称空间独立,同过指正联系,无论创建多少对象,都是开辟独立的内存空间,各个对象之间不能互相查找,干扰

查询顺序
对象的查询顺序:先从对象空间去找,对象的空间没有此变量或者方法,通过对象中的类对象指针去类中寻找.
类的查询顺序: 直接从类本身找.

# job1 = 'teacher'
# class A:
#     home = '老男孩教育'
#     name = '武大'
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#     def job(self):
#         print('我在开车.....')

# 查询顺序
# 对象的查询顺序:先从对象空间去找,对象的空间没有此变量或者方法,通过对象中的类对象指针去类中寻找.
# obj1 = A('oldboy',1000)
# obj1 = A('oldboy',1000)
# obj1 = A('oldboy',1000)
# obj1 = A('oldboy',1000)
# print(obj1.name)
# print(obj1.job)
# print(obj1.home)
# 类的查询顺序: 直接从类本身找.
# print(A.name)

# 对象的问题
# 无论创建多少对象,都是开辟独立的空间,各个对象之间不能互相查找,干扰.
# obj1 = A('oldboy',1000)
# obj2 = A('alex',10000)

# import girldriver
# girldriver.func()

组合: 给一个类的对象,封装一个属性,这个属性是另一个类的对象.

class Game_role:
    def __init__(self, name, ad, hp):
        self.name = name
        self.ad = ad
        self.hp = hp
    def attack(self,obj1):
        obj1.hp = obj1.hp - self.ad
        print('%s攻击%s,%s掉了%s血,还剩%s血'%(self.name,obj1.name,obj1.name,self.ad,obj1.hp))
    def package_weapon(self,wea):
        self.weapon = wea

class Sword:
    def __init__(self,name,ad):
        self.name = name
        self.ad = ad
    def fight(self,p1,p2):
        p2.hp = p2.hp - self.ad
        print('%s 用 %s 砍了 %s一刀,%s 还剩%s血' %(p1.name,self.name,p2.name,p2.name,p2.hp))
# aduan = Game_role('啊段', 10, 100)
# ts = Game_role('泰森', 120, 300)
# Slaughter_knife = Sword('杀猪刀',200)
# 这么写不好,动作的发起人是人而不是刀本身
# Slaughter_knife.fight(aduan,ts)
# 下面是符合逻辑的
# aduan.package_weapon(Slaughter_knife)  # 给aduan 这个对象封装了一个weapon属性这个属性值为Slaughter_knife
# aduan.weapon.fight(aduan,ts)
# ts.attack(aduan)
# print(aduan.weapon)
# print(aduan.weapon.name)
# aduan.weapon.fight(aduan,ts)

原文地址:https://www.cnblogs.com/linga/p/9239747.html