U6面向对象设计

Unit6 面向对象设计

这是编程思想的差别,相比与C语言的面向对象设计,大概就是由各种功能的方法组成项目,比较具体,缺少抽象,对于类似的操作不能很好的复用。在语言语法上多了类Class,继承,多态这些。

6.1 类

'''
Python 类/对象
Python 是一种面向对象的编程语言。
Python 中的几乎所有东西都是对象,拥有属性和方法。
类(Class)类似对象构造函数,或者是用于创建对象的“蓝图”。
'''
class MyClass:
    x = 5
p1 = MyClass()
print(type(p1))
print(p1.x)
#_init_()函数
'''
    所有类都有一个名为 __init__() 的函数,它始终在启动类时执行。
    使用 __init__() 函数将值赋给对象属性,或者在创建对象时需要执行的其他操作
    相当于 java里的无参构造
'''
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
p2 = Person("zhl",21)
print(p2.name)
print(p2.age)

#对象方法
class Person1:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def myFunc(self):
        print("hello my name is " + self.name)
p3 = Person1("zhl",21)
p3.myFunc()

#self参数
'''
    self 参数是对类的当前实例的引用,用于访问属于该类的变量。
    它不必被命名为 self,您可以随意调用它,但它必须是类中任意函数的首个参数
'''
class Person3:
    def __init__(mySillyObject, name, age):
        mySillyObject.name = name
        mySillyObject.age = age

    def myfunc(abc):
        print("hello my name is " + abc.name)
        print(f"my age is {abc.age}")
p4 = Person3("zhl",21)
p4.myfunc()

#修改对象属性
p4.age = 40
p4.myfunc()

#删除对象属性
del p4.age
#删除对象
del p4

class Person5:
    pass

6.2 继承

'''
Python 继承
继承允许我们定义继承另一个类的所有方法和属性的类。
父类是继承的类,也称为基类。
子类是从另一个类继承的类,也称为派生类。
'''
class Person:
  def __init__(self, fname, lname):
    self.firstname = fname
    self.lastname = lname

  def printname(self):
    print(self.firstname, self.lastname)
# 使用 Person 来创建对象,然后执行 printname 方法:
x = Person("Bill", "Gates")
x.printname()

#创建子类
class student(Person):
    pass
EM = student("Elon","Musk")
EM.printname()
'''
#添加_init_()函数
#次使用类创建新对象时,都会自动调用 __init__() 函数。
#当添加 __init__() 函数时,子类将不再继承父的 __init__() 函数。
子的 __init__() 函数会覆盖对父的 __init__() 函数的继承。
如需保持父的 __init__() 函数的继承,请添加对父的 __init__() 函数的调用
'''
class Student(Person):
  def __init__(self, fname, lname):
    Person.__init__(self, fname, lname)

x = Student("Elon", "Musk")
x.printname()
'''
    super()函数

'''
class Student(Person):
  def __init__(self, fname, lname):
    super().__init__(fname, lname)
x = Student("Elon", "Musk")
x.printname()
#和java一样,可以添加属性,添加方法

6.3 类属性和实例属性

class student:
    school = "CSUFT"
    #初始化方法
    def __init__(self, studentName, age):
        self.name = studentName
        self.age = age

    def show(self):
        print(f"my name is {self.name}, today {self.age} years old.")

    #静态方法
    @staticmethod
    def sm():
        #print(self.name)
        #self.show()
        print("这是一个静态方法,不能去调用实例属性,和使用方法")
    #类方法
    @classmethod
    def cm(cls):#cls -->class的简写
        #print(self.name)
        #self.show()
        print("这是一个类方法,不能调用实例属性,也不能调用实例方法")
#实例化
p1 =student("zhl",12)
#实例方法
p1.show()
#类属性直接调用
print(p1.name, p1.age)
print(p1.school)
#类方法
p1.cm()
#静态方法
p1.sm()

6.4 创建类对象

class Student:
    school = "CSUFT"
    def __init__(self, sn, age):
        self.name = sn
        self.age = age
    def show(self):
        print(f"我叫{self.name},今年{self.age}岁了")
#创建对象
stu1 = Student("小明",18)
stu2 = Student("小明1",18)
stu3 = Student("小明2",18)
stu4 = Student("小明4",18)
print(type(stu1))
print(type(stu2))
print(type(stu3))
print(type(stu4))
Student.school = "NO.1 Scholl CSUFT"
lst = [stu1,stu2,stu3,stu4]
for i in lst:
    i.show()

6.5 动态绑定属性和方法


class Student:
    school = "CSUFT"
    def __init__(self, sn, age):
        self.name = sn
        self.age = age
    def show(self):
        print(f"我叫{self.name},今年{self.age}岁了")
stu = Student("zhl",21)
print(stu.name, stu.age)
stu.name = "good man"
print(stu.name, stu.age)

6.6 python的getter和setter

class Student():
    #
    def __init__(self,name,age,gender):
        #self._name受保护,只能本类和子类去访问
        self._name = name
        #self.__age 标识是由的,只能类本身去访问
        self.__age = age
        self.gender = gender
    def _fun1(self):#protected
        print("子类以及本身可以访问")
    def __fun2(self):#private
        print("本身可以访问")
    def fun3(self):#default
        print("都可以访问")
    def show(self):
        self._fun1()
        self.__fun2()
        print(self._name)
        print(self.__age)
stu = Student("zhl", 21,"男")
#类的外部
print(stu._name)
#print(stu.__age)
stu._fun1()

#AttributeError: 'Student' object has no attribute '__fun2'. Did you mean: '_fun1'?
#stu.__fun2()
#私有的实例属性和方法不能直接访问
print(stu._Student__age)#可以访问
stu._Student__fun2()#可以访问

print(dir(stu))

'''
getter and setter
'''
class Student:
    def __init__(self, name, gender):
        self.__name = name
        self.__gender = gender
    # @property 修改方法,将方法转成属性使用
    @property
    def gender(self):
        return self.__gender
    @gender.setter
    def gender(self,value):
        if value != "男" and value != "女":
            raise ValueError("性别只能是'男’或'女'")
        self.__gender = value

    def getName(self):
        return self.__name

stu = Student("zhl","男")
print(stu.getName(),"的性别是",stu.gender)
print(type(stu.getName()))
print(type(stu.gender))

stu.gender = "女"
print(stu.getName(),"的性别是",stu.gender)
stu.gender = "1"
print(stu.getName(),"的性别是",stu.gender)


6.7继承

class Person:#默认继承了 Object
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show(self):
        print(f"hello i'm {self.name}, my age is {self.age}")
class Student(Person):
    #编写初始化的方法
    def __init__(self, name, age, stuNo):
        #调用父类的初始化方法
        super(Student, self).__init__(name, age)
        self.stuNo = stuNo
#Doctor 继承Person
class Doctor(Person):
    #初始化
    def __init__(self, name, age, department):
        super(Doctor, self).__init__(name, age)
        self.department = department
#实例化对象
stu1 = Student("张三",20,"1001")
stu2 = Student("李四",20,"1002")
stu1.show()
stu2.show()
doctor1 = Doctor("王五", 32,"外科")
doctor1.show()

6.8多继承

class Father1():
    def __init__(self,name):
        self.name = name
    def show1(self):
        print("父类1中的方法")

class Father2():
    def __init__(self,age):
        self.age = age
    def show2(self):
        print("父类2中的方法")
#多继承
class Son(Father1, Father2):
    def __init__(self, name, age, gender):
        #需要调用两个父类的初始化方法
        Father1.__init__(self, name)
        Father2.__init__(self, age)
        self.gender = gender
son1 = Son("张三",20,"男")
son1.show1()
son1.show2()

6.9重写

#c重写
class Person:#默认继承了 Object
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show(self):
        print(f"hello i'm {self.name}, my age is {self.age}")
class Student(Person):
    #编写初始化的方法
    def __init__(self, name, age, stuNo):
        #调用父类的初始化方法
        super(Student, self).__init__(name, age)
        self.stuNo = stuNo
    def show(self):
        super(Student, self).show()
        print("我是学生")
#Doctor 继承Person
class Doctor(Person):
    #初始化
    def __init__(self, name, age, department):
        super(Doctor, self).__init__(name, age)
        self.department = department
    def show(self):
        super(Doctor, self).show()
        print("我是医生")
#实例化对象
stu1 = Student("张三",20,"1001")
stu2 = Student("李四",20,"1002")
stu1.show()
stu2.show()
doctor1 = Doctor("王五", 32,"外科")
doctor1.show()

6.10多态

class Person():
    def eat(self):
        print("人吃饭")
class Cat():
    def eat(self):
        print("猫吃鱼")
class Dog():
    def eat(self):
        print("狗吃骨头")
def fun(obj):
    obj.eat()
#创建三个类对象
per = Person()
cat = Cat()
dog = Dog()
#调用fun函数
fun(per)
fun(cat)
fun(dog)

6.11 Object

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show(self):
        print(f"hello i'm{self.name}, age is {self.age}")
#实例化
per = Person("张三",20)
print(dir(per))
print(per) #自动调用了 __str__方法

6.12 __str__方法的重写

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show(self):
        print(f"hello i'm{self.name}, age is {self.age}")
    #重写
    def __str__(self):
        return "这是一个Person Class"
#实例化
per = Person("张三",20)
print(dir(per))
print(per) #自动调用了 __str__方法

6.12 深拷贝与浅拷贝

  1. 浅拷贝(Shallow Copy)

    • 浅拷贝创建一个新对象,其字段值与原始对象相同。如果字段是基本数据类型,那么复制的是基本数据类型的值;如果字段是对象的引用,则复制的是引用,而不是引用的对象本身。
    • 对于字段是对象引用的情况,浅拷贝后的新对象和原始对象会共享这些对象引用。这意味着如果通过新对象改变了引用指向的对象,原始对象中相应的对象也会被改变。
    • 浅拷贝可以通过多种方式实现,例如在Python中可以使用copy模块的copy()函数。
  2. 深拷贝(Deep Copy)

    • 深拷贝创建一个新对象,并且递归地复制所有对象的字段值。这意味着如果字段是对象的引用,那么深拷贝会创建这些对象的副本,而不是仅仅复制引用。
    • 深拷贝后的新对象与原始对象完全独立,对新对象的任何修改都不会影响原始对象。
    • 深拷贝通常需要更多的时间和内存,因为它需要创建更多的对象副本。
    • 在Python中,可以使用copy模块的deepcopy()函数来实现深拷贝。
class CPU():
    pass
class Disk():
    pass

class Computer():
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk
'''
输出结果
<__main__.Computer object at 0x000002ADC80F9010> 子对象的内存地址 <__main__.CPU object at 0x000002ADC80F8F90> <__main__.Disk object at 0x000002ADC80F8FD0>
<__main__.Computer object at 0x000002ADC80F9010> 子对象的内存地址 <__main__.CPU object at 0x000002ADC80F8F90> <__main__.Disk object at 0x000002ADC80F8FD0>
'''
cpu= CPU()
disk = Disk()
com = Computer(cpu,disk)
com1 = com
print(com, "子对象的内存地址",com.cpu, com.disk)
print(com1, "子对象的内存地址",com1.cpu, com1.disk)
print("*"*50)
#浅拷贝
import copy
com2 = copy.copy(com)
print(com, "子对象的内存地址",com.cpu, com.disk)
print(com2, "子对象的内存地址",com2.cpu, com2.disk)
print("*"*50)
#深拷贝
com3 = copy.deepcopy(com)
print(com, "子对象的内存地址",com.cpu, com.disk)
print(com3, "子对象的内存地址",com3.cpu, com3.disk)
posted @ 2024-10-31 19:21  zhlzn  阅读(6)  评论(0编辑  收藏  举报