面向对象

前言:

面向对象(oop)是一种编程方法,编程思想,适用于中大型项目;

面向过程也是一种编程思想,适用于小型项目。

面向过程 和 面向对象 都可以实现某个编程目的,面向过程考虑的是 实现的细节;面向对象考虑的是 结果(谁能做这件事)。

 

面向对象

  类class:是对具有相同特征或者行为的事物的统称,是抽象的,不能直接使用(指代多个事物)

  对象:是由类创建出来的一个具体存在的事物,可以直接使用(指代一个具体事物)

 

类的构成

  1、类名:标识符规则、见名知意、大驼峰(所有单词首字母大写)命名法

  2、属性:事物的特征

  3、方法:事物的行为

 

面向对象代码的步骤:

  1、设计类(找类的三要素)

  2、定义类

  3、创建对象(实例化对象)

  4、由对象调用类中的方法

 

面向对象基本语法:

  # 定义类

  class 类名:

    def 方法名(self):  # 方法的本质是函数

      pass

  

  # 创建对象(实例化对象)

  变量 = 类名()  # 一般将这个变量成为对象(本质:变量中保存的是对象的引用地址)

 

  # 调用类中的方法

  对象.方法名()  # 对象就是上面那个变量

 

# 例子:小猫爱吃鱼,小猫要喝水

 

self参数

  1、self是形参,名字可以任意,但习惯性上叫self

  2、self是一个普通参数,调用函数的时候需要传递实参,而目前Python解释器自动将调用这个方法的对象作为参数传递给self(即:self就是调用这个方法的对象,上述例子,self就是mi)

 

类外面添加属性,只适用于该操作对象

 

类里面添加属性,需用到__init__ 方法

  初始化对象,给对象添加属性,若属性值是变化的,则可以将这个属性的值作为参数传递,创建对象的时候传递实参;

  创建对象的时候,__init__方法会自动调用

 

 

__str__方法:用于print(对象)时返回字符串

 

 dir(对象) 返回对象内的所有属性和方法

 

 面向对象案例

 1 '''
 2 面向对象案例一:
 3     小明体重75公斤
 4     小明每次跑步会减肥0.5公斤
 5     小明每次吃东西会增加1公斤
 6 '''
 7 
 8 class Human:
 9     def __init__(self, name, weight):
10         self.name = name
11         self.weight = weight
12     
13     def __str__(self):
14         return f'{self.name}现在的体重是{self.weight}公斤'
15         
16     def run(self):
17         self.weight -= 0.5
18         
19     def eat(self):
20         self.weight += 1
21         
22 if __name__ == '__main__':
23     xiaoming = Human('小明',75)
24     for i in range(10):     # 跑了十次步
25         xiaoming.run()
26     for j in range(3):      # 吃了三次东西
27         xiaoming.eat()
28     print(xiaoming)
 1 '''
 2 面向对象案例二:
 3     房子有户型、总面积、家具名称列表(新房子没有任何家具)
 4     家具有名字、占地面积:
 5         席梦思 占地 4 平米
 6         衣柜   占地 2 平米
 7         餐桌   占地 1.5平米
 8         
 9     将以上三件家具添加到房子中
10     打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表
11 '''
12 
13 class Jj:
14     '''
15     类名:Jj
16     属性:家具名name,占地面积area
17     方法:__str__() 返回XXX的占地面积是XXX
19     '''
20     def __init__(self, name, area):
21         self.name = name
22         self.area = area
23 
24     def __str__(self):
25         return f'{selef.name}的占地面积是{self.area}'
26     
27     
28 class House:
29     '''
30     类名:House
31     属性:户型hx,总面积zmj,剩余面积rarea,家具列表jjs
32     方法:addJj() 往家具列表中添加家具名,并修改剩余面积
33          __str__() 返回房子的基本情况
34     '''
35     
36     def __init__(self, hx, zmj):
37         self.hx=hx
38         self.zmj = zmj
39         self.rarea = zmj
40         self.jjs = []
41 
42     def addJj(self, JjObject):
43         if self.rarea >= JjObject.area:
44             self.jjs.append(JjObject.name)
45             self.rarea -= JjObject.area
46         else:
47             print(f'剩余面积为{self.rarea},{JjObject.name}占地{JjObject.area},放不下')
48     def __str__(self):
49         return f'户型:{self.hx},总面积:{self.zmj},剩余面积:{self.rarea},家具名称列表:{self.jjs}'
50 
51 if __name__ == '__main__':
52     xi = Jj('席梦思', 4)
53     gui = Jj('衣柜', 2)
54     zhuo = Jj('餐桌', 1.5)
55 
56     chen = House('A型', 100)
57     chen.addJj(xi)
58     chen.addJj(gui)
59     chen.addJj(zhuo)
60     print(chen)

面向对象的三大特征:封装、继承、多态 

继承

  1、继承描述的是类与类之间的关系 is ... a

  2、减少代码冗余,重复代码不需要多次书写,提交编程效率

  3、继承具有传递性:子类可以继承父类的父类的属性和方法

  4、对象使用属性/调用方法飞顺序:自己类->父类->父类的父类->...->object类,一直没有就报错

  语法:

 1 class A(object):    # 默认继承object类,object类是Python中最原始的类
 2     pass
 3 
 4 class B(A):         # 类B继承类A
 5     pass
 6 
 7 '''
 8 类A:父类 或 基类
 9 类B:子类 或 派生类
10 子类继承父类之后,子类对象可以直接使用父类中的属性和方法
11 '''

  案例:

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print(f'{self.name}在吃东西')
        
    def sleep(self):
        print(f'{self.name}在睡觉')
        
class Cat(Animal):
    def zhua(self):
        print(f'{self.name}在抓老鼠')
        

class Dog(Animal):
    def kan(self):
        print(f'{self.name}在看门')


class Xiaotianquan(Dog):
    def fly(self):
        print(f'{self.name}在飞')
        

if __name__ == '__main__':
    peiqi = Animal('佩奇', 2)
    peiqi.eat()
    peiqi.sleep()

    tom = Cat('Tom', 4)
    tom.eat()
    tom.sleep()
    tom.zhua()
    
    wangcai = Dog('旺财', 5)
    wangcai.eat()
    wangcai.sleep()
    wangcai.kan()
    
    xiao1 = Xiaotianquan('哮1', 18)  # 子类对象不管有没有用到父类的属性和方法,都需要在实例化对象的时候传父类的参数
    xiao1.eat()
    xiao1.sleep()
    xiao1.kan()
    xiao1.fly()

  重写(override):

    当子类定义了与父类一样的方法,且父类中的代码不能满足子类对象的需要

    分类:

      1、覆盖式重写:直接在子类中定义与父类方法名一样的方法

      2、扩展式重写:父类中的功能还需要,只是添加了新的功能

        ① 子类中定义与父类一样的方法名

        ② 子类中方法中,使用super().方法名() 调用父类中的功能

        ③ 书写新的功能

        

#  覆盖式重写
class Dog:
    def dark(self):
        print('汪汪叫....')
        
class XTQ(Dog):
    def dark(self):
        super().dark()
        print('嗷嗷叫....')

x = XTQ()
x.dark()

汪汪叫....
嗷嗷叫....

 

 

多态

  一种调用代码的技巧,不同的子类对象调用相同的方法,产生不同的执行结果(本质:对象调用方法,先去本身的类里面找方法,没有就再去父类找)

# 多态实例
class Dog:
    def game(self):
        print('普通狗在简单的玩耍')

class XTQ(Dog):
    def game(self):
        print('哮天犬在天上玩耍')

class Person:
    def p_d(self, dogObj):      # dogObj可以是Dog类对象,也可以是Dog类的子类对象(XTQ类)
        print('人在和狗玩耍')
        dogObj.game()
        
if __name__ == '__main__':
    Lily = Person()
    hei = Dog()
    xtq = XTQ()
    Lily.p_d(hei)
    Lily.p_d(xtq)
    # hei和xtq是不同的子类对象,它们调用了相同的方法game,产生了不同的执行结果

 

私有和公有

  有权限:

    直接定义的属性和方法就是公有的,可以在任何地方访问和使用

   私有权限:

    只能在类内部定义(class关键字的里面),只需要在属性名和方法名前面加上__就变成私有的了

    私有只能在当前类的内部使用,不能在类外部和子类直接使用

  案例:

# 案例:私有属性__age只能在Person类中使用,外部无法使用和修改
class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age       # 定义一个私有的属性__age
        
    def __str__(self):
        return f'{self.name},{self.__age}'      # 使用的是私有属性__age

if __name__ == '__main__':
    tom = Person('汤姆', 10)
    print(tom.__age)    # 报错,类外部无法使用私有属性__age
    print(tom)          # 汤姆,10
    tom.__age = 100     # 添加一个公有属性__age,无法修改私有属性__age
    print(tom.__age)    # 打印刚添加的公有属性100
    print(tom)          # 汤姆,10 打印的还是私有属性10
    
    print(dir(tom))     # 其中'_Person__age', '__age' 分别是私有属性和公有属性
    

    
# 案例:可以定义一个公有方法set_age,允许类外部修改私有属性__age
class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age       # 定义一个私有的属性__age

    def __str__(self):
        return f'{self.name},{self.__age}'      # 使用的是私有属性__age

    # 定义一个公有方法来修改私有属性__age
    def set_age(self, new_age):
        self.__age = new_age

if __name__ == '__main__':
    tom = Person('汤姆', 10)
    tom.set_age(1000)
    print(tom)          # 汤姆,1000, 修改了私有方法__age=1000

 

 

 

     

 

posted @ 2023-12-16 20:22  Sakura媛媛  阅读(44)  评论(0)    收藏  举报