自学内容网 自学内容网

python——面向对象

一、面向对象编程

1.1 面向过程与面向对象

面向过程和面向对象都是一种编程方式,只不过再设计上有区别。

1.1.1 面向过程pop:

举例:孩子上学

1. 妈妈起床

2. 妈妈洗漱

3. 妈妈做饭

4. 妈妈把孩子叫起来

5. 孩子起床

6. 孩子洗漱

7. 孩子吃饭

8. 妈妈给孩子送学校去

最为典型就是我们的C语言编程。

1》导入各种外部库

2》设计各种全局变量

3》写一个函数

4》写一个函数

5》........

6》写一个main主函数作为程序入口部分

- 面向过程的编程思想将一个功能分解为一个一个小的步骤, 我们通过完成一个一个的小的步骤来完成一个程序

- 这种编程方式,符合我们人类的思维,编写起来相对比较简单

- 但是这种方式编写代码的往往只适用于一个功能, 如果要在实现别的功能,即使功能相差极小,也往往要重新编写代码, 所以它可复用性比较低,并且难于维护

优点:简单直观、性能高效、代码简洁。

缺点:不易维护、不易扩展、代码重用性低。

1.1.2 面向对象oop:

举例:孩子上学

1》妈妈 送 孩子 上学 python、java、C++都是面向对象的编程方式。 以python为例

1》导入各种库

2》设计各种全局变量

3》设计你所需要的类——妈妈类、孩子类

4》main主函数可有可无

- 面向对象的编程思想,将所有的功能统一保存到对应的对象中 比如,妈妈功能保存到妈妈的对象中,孩子的功能保存到孩子对象中 。要使用某个功能,直接找到对应的对象即可

- 这种方式编写的代码,比较容易阅读,并且比较易于维护,容易复用。

- 但是这种方式编写,不太符合常规的思维,编写起来稍微麻烦一点

优点:模块化、安全性高、代码重用性高。

缺点:学习难度大、性能开销大、调试困难。

1.2 类 和 对象

目前我们所学的python中的内置类型都是对象——内置对象,内置对象有时候不能满足我们的需求,需要自定义一些对象。

10, 20, 30, -40, a=10, b=20等等等,都是整数,对其进行抽象——int类。

python 中一切都是对象。

类也是一个对象。

1.2.1 类的定义 与 实例化对象

语法格式1:
class ClassA:
    # 公共的属性
    def __init__(self):
        pass
    def fun1(self):
        pass
    def fun2(self):
        pass

语法格式2:
class ClassA(object):
    # 公共的属性
    def __init__(self):
        pass
    def fun1(self):
        pass
    def fun2(self):
        pass
        
 实例化对象的语法:
 1》无参
     对象名 = 类名()
 2》有参
     对象名 = 类名(参数列表)                                     

例举 

# 设计类
class student:
    name = None
    age = None
    gander = None
# 创建对象
student1 = student()
# 给对象赋值
student1.name = '小明'
student1.age = 18
student1.gender = '男'
# 获取对象中的信息
print(student1.name,student1.age,student1.gander)

1.2.2 访问属性/方法

使用符号 . 进行访问

# 访问属性

对象名.属性

# 访问方法

对象名.方法名()

1.2.3 对象与类的关系【1】

  1. 对象拥有类的所有属性和方法
  2. 对象的属性和方法可以单独添加、删除、修改
  3. 对象与对象之间的属性和方法不可共享
  4. 对象不能独自创建,必须依托于类,类可以实例化N个对象
#创建一个闹钟类
class clock:
    id = None
    price = None
    def ring(self):
        import winsound #python内置模块是让电脑响    
        winsound.Beep(2000,3000)#频率和时间
        print(f'电脑编号{self.id},电脑价格{self.price}')
#闹钟1
clock1 = clock()
clock1.id =12344
clock1.price = 19.99
clock1.ring()

#闹钟2
clock2 = clock()
clock2.id = 12345
clock2.price = 29.99
clock2.ring()

1.2.3 对象与类的关系【2】

from types import MethodType


class student:
    def __init__(self,name):
        self.name = name

    def fun1(self):
        print(f'{self.name}会唱歌')

s1 = student('刘')
s2 = student('坤哥')

s1.fun1()#刘会唱歌
s2.fun1()#坤哥会唱歌

def Ctrl(self):
    print(f'{self.name}会穿背带裤打篮球')

s2.Ctrl=MethodType(Ctrl,s2)

s2.Ctrl()#坤哥会穿背带裤打篮球
还可以使用以下函数的方式来访问属性:
  • getattr(obj, name[, default]) : 访问对象的属性。
  • hasattr(obj,name) : 检查是否存在一个属性。
  • setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
  • delattr(obj, name) : 删除属性。

1.2.5 魔方方法——构造函数 与 析构函数

  1. __init__ 构造函数:完成对象的初始化工作,方便统一管理、调用类创建对象时,自动执行。
  2. __del__ 析构函数:删除对象时执行一些操作,自动执行。
  3. __str__ 打印方法:输出执行信息,自动执行。
class Animal:
    #构造函数
    def __init__(self,name,call):
        self.name = name
        self.call = call

    #打印方法
    def __str__(self):
        return f'{self.call},你在{self.name}叫什么'

    #析构函数
    def __del__(self):
        print(f"{self.name}消音成功")

dog = Animal('狗','汪汪汪')
cat = Animal('猫','喵喵喵')

print(dog)
print(cat)
"""
汪汪汪,你在狗叫什么
喵喵喵,你在猫叫什么
狗消音成功
猫消音成功
"""

1.2.6 类属性/方法 与 实例对象属性/方法 与 静态方法

class Bank(object):
    """
    定义了一个银行卡类,用于初始化、存钱、取钱
    """
    total_money = 0

    def __init__(self, name, money):
        self.name = name
        Bank.total_money += money    #改为self.

    def save(self, money):
        Bank.total_money += money

    def draw(self, money):
        Bank.total_money -= money

b1 = Bank('张三', 1000)
print(b1.total_money)
b1.save(5000)
print(b1.total_money)
b1.draw(3000)
print(b1.total_money)

b2 = Bank('李四', 8888)
print(b2.total_money)
b2.save(10000)
print(b2.total_money)
类方法、实例方法、静态方法
class student:
    #定义一个学生类
    grade = 'py24101'

    @classmethod
    def clas_fun(cls):
        """类方法中只能调用类属性和类方法"""
        print(cls.grade)

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

    def fun1(self):
        """实例方法中能调用类属性、实例属性"""
        print(f"实例方法中输出类属性{self.grade}, 输出实例属性{self.name}")

    @staticmethod
    def sta_fun(x):
        print(f"{x}静态方法一般实现与类和对象无关联的操作,例如:游戏说明书等")

s1 = student('小明',18)
#调用类方法
#方法一
student.clas_fun()#py24101
#方法二
s1.clas_fun()#py24101

#如何调用实例对象
#方法一
student.fun1(s1)#实例方法中输出类属性py24101, 输出实例属性小明
#方法二
s1.fun1() #实例方法中输出类属性py24101, 输出实例属性小明

# 如何调用静态变量
#方法一
student.sta_fun(2)#2静态方法一般实现与类和对象无关联的操作,例如:游戏说明书等
#方法二
s1.sta_fun(2) #2静态方法一般实现与类和对象无关联的操作,例如:游戏说明书等

1.2.7 Python的内置类属性

  • __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
  • __doc__ :类的文档字符串
  • __name__: 类名
  • __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  • __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
class Student(object):
    """
    定义一个学生类
    属性:名字 年龄
    方法:method_1 method_2
    """
    name = '张三'
    age = 18

    def method_1(self):
        pass

    def method_2(self):
        pass

print(Student.__dict__)
print(Student.__doc__)
print(Student.__name__)
print(Student.__module__)
print(int.__module__)
print(Student.__bases__)
"""
{'__module__': '__main__', '__doc__': '\n    定义一个学生类\n    属性:名字 年龄\n    方法:method_1 method_2\n    ', 'name': '张三', 'age': 18, 'method_1': <function Student.method_1 at 0x0000023EBF1A4AE0>, 'method_2': <function Student.method_2 at 0x0000023EBF1A4C20>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>}

    定义一个学生类
    属性:名字 年龄
    方法:method_1 method_2
    
Student
__main__
builtins
(<class 'object'>,)
"""

1.3 类的封装【私有属性与方法】

封装是类的三大特性之一。

封装指的是隐藏对象中一些不希望让外部所访问的属性或方法。

python中封装其实是通过设置访问权限来体现的,私有属性和私有方法是控制访问权限的组成部分。

1.3.1 私有属性

在类的内部使用,不希望外部直接访问的变量。

在python中,使用双下划线作为前缀来定义私有属性。

私有属性在类外不能访问

class bank:
    def __init__(self,name,pwd):
        self.name = name
        self.__pwd = pwd
        # 为了在某些需要的时候,访问到私有属性,所以需要在类内部设置两个接口

    def get_pwd(self):
        return self.__pwd

    def set_pwd(self,newpwd):
        self.__pwd = newpwd

user = bank("小明",'123456')

print(user.name)#小明
# print(user.__pwd) 会报错
print(user.get_pwd())#123456
user.set_pwd('456789')
print(user.get_pwd()) #456789

1.3.2 私有方法

和私有属性是一样的。

class Bank(object):
    """
    定义了一个银行卡类
    属性:name     pwd密码【我不希望外部访问】
    """
    def __init__(self, name, pwd):
        self.name = name
        self.__pwd = pwd

    def __info(self):
        print(f"名字{self.name}, 密码{self.__pwd}")

    def get_info(self):
        self.__info()

# Bank.__info() 报错
b1 = Bank('李四', '123456')
# b1.__info()   报错
b1.get_info()

1.3.3 属性装饰器

属性装饰器是实现把方法转为属性的装饰器。

作用:

  1. 把方法转为属性,便于操作属性
  2. 实现对属性的更改(验证)、查看、删除

class 类名:

        def __init__(self,name):

                self.name = name

        @property

        def 函数名(self):

                return self.name

        @函数名.setter

        def 函数名(self,m)

                self.name +=m

         

class bank:
    def __init__(self,name ='',money = 0): #可以在里面定义初始值
        self.name = name
        self.__money = money

    @property
    def my_money(self):
        return self.__money

    @my_money.setter
    def my_money(self,m):
        self.__money+=m

user = bank('小明',1000)

user.my_money = 900
print(user.my_money) #1900

1.4 类的继承

面向对象的编程带来的主要好处之一就是代码的重用,实现这种重用的方法之一就是通过继承机制。

通过继承创建的新类称之为【子类】或者【派生类】,被继承的类称之为【父类】、【基类】、【超类】。

1.4.1 继承语法格式

class 子类名(父类名列表):

        pass

class Parent(object):
    """
    定义父类
    """
    par_attr = 100

    def __init__(self):
        print("初始化父类")

    def par_fun1(self):
        print("父类方法1")

    def par_fun2(self):
        print("父类方法2")

class Child(Parent):
    """
    定义子类
    """
    child_attr = 666
    def __init__(self):
        print("初始化子类")

    def child_fun1(self):
        print("子类方法1")

c1 = Child()
print(c1.child_attr)
c1.child_fun1()

print(c1.par_attr)
c1.par_fun1()
c1.par_fun2()

1.4.2 多继承语法【明白即可,不建议乱用】

如果在继承的元组()里面有一个以上的类,就称之为多继承

class a:
    pass
class b:
    pass
class c:
    pass
class d(a,b,c):
    pass

D = d()
print(d.mro())#[<class '__main__.d'>, <class '__main__.a'>, <class '__main__.b'>, <class '__main__.c'>, <class 'object'>] 查顺序
print(d.__bases__) #(<class '__main__.a'>, <class '__main__.b'>, <class '__main__.c'>)查父类

1.4.3 继承重写父类方法

如果你的父类方法不能满足你得要求,你可以在之类中重写父类的方法。

# 重写
class Parent(object):
    def method(self):
        print(f"{self}的方法")

class Child(Parent):
    def method(self):
        print("xxxxxxxxxx")
        print(f"子类重写父类ri{self}的方法")

c = Child()
c.method()

 这里列出了一些通用的功能,可以在自己的类重写:

__init__ ( self [,args...] )构造函数

简单的调用方法: obj = className(args)

__del__( self ) 析构方法

简单的调用方法 : del obj

__repr__( self ) 转化为供解释器读取的形式

简单的调用方法 : repr(obj)

__str__( self ) 用于将值转化为适于人阅读的形式

简单的调用方法 : str(obj)

__cmp__ ( self, x ) 对象比较

简单的调用方法 : cmp(obj, x)

1.4.4 python继承特点

  • 在子类中如果需要父类的构造方法,需要显式调用父类的构造方法,或者不重写父类的构造方法。__init__()
  • 在子类中调用父类的方法,需要显式调用,且第一个参数self不能省略
不重写父类构造方法 
class father:
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def sum(self):
        print(f'{self.x},{self.y}')

class child(father):
    def fun(self):
        print(f'{self.x},{self.y}')

stu = child(1,2)
stu.fun() #1,2

重写父类构造方法、里面显式调用父类构造方法
class father:
    def __init__(self,x,y):
        self.x = x
        self.y = y

class child(father):
    def __init__(self,x,y,z):
        father.__init__(self,x,y)
        self.z = z
    def fun(self):
        print(self.x,self.y,self.z)
stu = child(1,2,3)
stu.fun() #1,2,3

用super().方法/成员变量
class father:
    def __init__(self,x,y):
        self.x = x
        self.y = y

class child(father):
    def __init__(self,x,y,z):
        super().__init__(x,y)
        self.z = z
    def fun(self):
        print(self.x,self.y,self.z)
stu = child(1,2,3)
stu.fun() #1,2,3

1.4.5 运算符重载

在Python中,并没有像其他语言(如C++)中那样的内置机制来重载运算符。但是,你可以通过定义特定的方法来模拟运算符重载的行为。

以下是一些常见运算符以及它们对应的特殊方法:

加法:+ 对应 __add__

减法:- 对应 __sub__

乘法:* 对应 __mul__

除法:/ 对应 __truediv__

取模:% 对应 __mod__

幂运算:** 对应 __pow__

位运算:

位运算:>> 对应 __rshift__

位运算:& 对应 __and__

位运算:| 对应 __or__

位运算:^ 对应 __xor__

class a:
    def __init__(self,x):
        self.x = x
    def __add__(self, other):
        return self.x + other.x
b = a(3)
c = a(4)
print(b+c) #7


class d:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def __add__(self, other):
        return self.x*other.y+self.y*other.x

e = d(2,3)
f = d(4,5)
print(e+f)#22

1.5 类的多态

python中的多态也可以通过方法重写进行。

同一个方法,不同对象显式的结果不同

 class Animal:
    def speak(self):
        pass
class Dog(Animal):
    def speak(self):
        print('汪汪汪')
class Cat(Animal):
    def speak(self):
        print('喵喵喵')

def Animal_speak(animal:Animal):
    animal.speak()

dog = Dog()
cat = Cat()

Animal_speak(dog)#汪汪汪
Animal_speak(cat)#喵喵喵

1.创建学生类Person。

2.添加静态方法,showInfo:

(1)显示信息“龙的传人”;

3.添加类属性:country,国籍,默认值为“中国“。

4.添加类属性:nation,民族,默认值为“汉族“。

5.添加构造方法,添加如下对象属性:

(1)name,保存学生姓名,默认值为空字符串。

(2)age,保存学生年龄,默认值为0。

(3)birth,保存出生日期,默认值为空字符串。

(4)money,保存工资收入,私有权限,默认值为0。

6.添加类方法,获取两个类属性的值。

7.添加魔法方法,将所有属性用格式化字符串组合成一个字符串后返回。

(1)格式如下: 国籍:中国 民族:汉 姓名:XXX 年龄:XXX 出生日期:XXX

8.添加setName方法,修改对象属性name。

9.添加getName方法,获得对象属性name的值。

10.添加返回age值的方法getAge,利用属性装饰器修饰该方法,并对age值进行修改。 11.添加setBirth方法,修改对象属性birth。

12.添加getBirth方法,获得对象属性birth的值。

13.添加私有属性money的set和get方法。

14.添加对象方法info,输出当前对象的个人信息:

(1)格式如下:姓名—年龄—出生日期—存款

15.添加主程序入口,完成如下任务:

(1)调用静态方法: ①提示:通过对象调用 ②提示:通过类名调用;

(2)创建一个对象。

(3)修改对象的所有对象属性。

(4)通过对象方法获得对象的所有属性值,并显示。

(5)调用info显示对象信息。

(6)调用对象的打印方法,输出信息;

(7)再次修改所有对象的属性。

(8)再次调用对象的打印方法。

from tkinter.font import names


class Person:
    country = '中国'
    nation = '汉族'

    @staticmethod
    def showInfo():
        print('龙的传人')

    def __init__(self,name = '',age = 0,birth = '',money = 0):
        self.name = name
        self.age = age
        self.birth = birth
        self.__money = money

    @classmethod
    def func(cls):
        print(cls.country,cls.nation)

    def __str__(self):
        return f' 国籍:{self.country} \n 民族:{self.nation} \n 姓名:{self.name} \n 年龄:{self.age} \n 出生日期:{self.birth}'

    def setName(self,name):
        self.name = name

    def getName(self):
        print(self.name)

    @property
    def getAge(self):
        return self.age
    @getAge.setter
    def getAge(self,newage):
        self.age = newage

    def setBirth(self):
        return self.birth
    def getBirth(self,birth):
        self.birth = birth

    def set_money(self):
        return self.__money
    def get_money(self,money):
        self.__money = money

    def info(self):
        print(f'姓名:{self.name} 年龄:{self.age} 出生日期:{self.birth} 存款:{self.__money}')


user = Person()
user.showInfo()
user.setName("张三")
user.getAge = 25
user.getBirth('1999-09-30')
user.get_money(20000)
user.info()
print(user)
user.setName('小明')
user.getAge = 19
user.getBirth('2005-07-30')
user.get_money(2000)
print(user)


原文地址:https://blog.csdn.net/2303_76544787/article/details/143749495

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!