首页 > 编程语言 >第九章面向对象程序设计

第九章面向对象程序设计

时间:2024-07-21 21:30:19浏览次数:18  
标签:__ name 第九章 self 面向对象 print 程序设计 age def

两大编程思想

面向过程
功能上的封装,典型代表:C语言
面次对象
属性和行为上的封装:典型代表Java和Pathon

步骤确定:面向过程


类和对象

类:由N多个对象抽取出‘像’的属性和行为从而归纳总结出来的一种类别

在Pathon中一切皆对象

点击查看代码
示例9-1查看对象的数据类型
a=10
b=9.8
s='hello'
print(type(a))
print(type(b))
print(type(s))

1、自定义数据类型的语法结构为

calss 类名():
    pass
#类名首字母大写

2、创建对象的语法格式为:
对象名=类名()

点击查看代码
示例9-2自定义数据类型
#编写一个Person
class Person:
    pass
#编写一个Cat类
class Cat:
    pass

#编写一个Dog类
class Dog:
    pass

#编写一个Student类
class Student():
    pass
示例9-3创建自定义类型的对象
#编写一个Person
class Person:
    pass
#编写一个Cat类
class Cat:
    pass

#编写一个Dog类
class Dog:
    pass

#编写一个Student类
class Student():
    pass

#创建类的对象
#对象名=类名()

#创建一个Person类型的对象
per=Person()#per就是Person类型的对象
c=Cat()#c就是Cat类型的对象
d=Dog()#d就是Dog类型的对象
stu=Student()#stu就是Student类型的对象

print(type(per))
print(type(c))
print(type(d))
print(type(stu))

点击查看代码
示例9-4类属性和实例属性的定义
class Student():
    #类属性,定义在类中,方法外的变量
    school='北京XXX教育'
     #初始化方法
    def __init__(self,xm,age):#xm,age是方法的参数,是局部变量,xm,age的作用域在__int__方法
        self.name=xm #=左侧是实例属性,xm是局部变量,将局部变量的值xm赋值给实例属性self.name
        self.age=age #实例对象和局部变量的名称可以相同
        
示例9-5类的组成
class Student():
    #类属性,定义在类中,方法外的变量
    school='北京XXX教育'
     #初始化方法
    def __init__(self,xm,age):#xm,age是方法的参数,是局部变量,xm,age的作用域在__int__方法
        self.name=xm #=左侧是实例属性,xm是局部变量,将局部变量的值xm赋值给实例属性self.name
        self.age=age #实例对象和局部变量的名称可以相同

    #定义在类中的函数称为方法,自带参数self
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁了')

    #静态方法
    @staticmethod
    def sm():
        #print(self.name)
        #self.show()
        print('这是一个静态方法,不能调用实例属性,也不能调用实例方法')

    #类方法
    @classmethod
    def cm(cls):#cls--->class的简写
        # print(self.name)
        # self.show()
        print('这是一个类方法,不能调用实例属性,也不能调用实例方法')


#创建类的对象
stu=Student('ysj',18)#为什么传了两个参数,因为__int__方法中,有两个形参.self,是自带的参数,无需手动传入
#实例属性,是使用对象名打点调用的
print(stu.name,stu.age)

#类属性,直接使用类名打点调用
print(Student.school)

#实例方法,使用对象名进行打点调用
stu.show()

#类方法,@classmethon进行修饰的方法,直接使用类名打点调用
Student.cm()

#静态方法,@staticmethon进行修饰的方法,直接使用类名打点调用
Student.sm()

示例9-6编写学生类并创建4个学生对象
class Student():
    #类属性,定义在类中,方法外的变量
    school='北京XXX教育'
     #初始化方法
    def __init__(self,xm,age):#xm,age是方法的参数,是局部变量,xm,age的作用域在__int__方法
        self.name=xm #=左侧是实例属性,xm是局部变量,将局部变量的值xm赋值给实例属性self.name
        self.age=age #实例对象和局部变量的名称可以相同

    # 定义在类中的函数称为方法,自带参数self
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁了')

#根据’图纸‘可以创建出N多个对象
stu=Student('ysj','18')
stu2=Student('陈玫玫','20')
stu3=Student('玛丽',21)
stu4=Student('Marry',23)#等号右侧都是Student()

print(type(stu))
print(type(stu2))
print(type(stu3))
print(type(stu4))

Student.school=('派森教育') #给类的类属性赋值

#将学生对象存储到列表中
lst=[stu,stu2,stu3,stu4]#列表中的元素是Student类型的对象
for item in lst:#item的hi列表中的元素,是Student类型的对象
    item.show() #对象名打点调用实例方法



动态绑定属性和方法

每个对象的属性名称相同,但属性值不同
可以为某个对象绑定独有属性和方法

点击查看代码
示例9-7动态绑定属性和方法
class Student():
    #类属性,定义在类中,方法外的变量
    school='北京XXX教育'
     #初始化方法
    def __init__(self,xm,age):#xm,age是方法的参数,是局部变量,xm,age的作用域在__int__方法
        self.name=xm #=左侧是实例属性,xm是局部变量,将局部变量的值xm赋值给实例属性self.name
        self.age=age #实例对象和局部变量的名称可以相同

    # 定义在类中的函数称为方法,自带参数self
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁了')

#创建两个Student类别的对象
stu=Student('ysj',18)
stu2=Student('陈玫玫',20)
print(stu.name,stu.age)
print(stu2.name,stu2.age)

#为stu2动态绑定一个实例属性
stu2.gender='男'
print(stu2.name,stu2.age,stu2.gender)


#print(stu.gender)#AttributeError: 'Student' object has no attribute 'gender'

#动态绑定方法
def introduce():
    print('我是一个普通的函数,我被动态绑定成了stu2对象的方法')
stu2.fun=introduce #函数的赋值
#fun 是stu2 对象的方法
#调用
stu2.fun()


面向对象的三大特征

1、封装

点击查看代码
示例9-8权限控制
class Student():
    #首尾双下划线
    def __init__(self,name,age,gender):
        self._name=name  #self.name受保护,只能本类和子类访问
        self.__age=age  # self.__age表示私有的,只能类本身去访问
        self.gender=gender #普通的实例属性,类的内部,外部及子类都可以访问

    def _fun1(self): #受保护的
        print('子类及本身可以访问')

    def __fun2(self): #私有的
        print('只有定义的类可以访问')

    def show(self): #普通的实例方法
        self._fun1() #类本身访问受保护的方法
        self.__fun2() #类本身访问私有的方法
        print(self._name) #受保护的实例属性
        print(self.__age) #私有的实例属性

#创建一个学生类的对象
stu=Student('陈玫玫',20,'女')
#类的外部
print(stu._name)
#print(stu.__age)#AttributeError: 'Student' object has no attribute '__age'. Did you mean: '_name'?

#调用受保护的实例方法
stu._fun1()#子类及本身可以访问
#私有方法
#stu.__fun2()#AttributeError: 'Student' object has no attribute '__fun2'. Did you mean: '_fun1'?
print(stu._Student__age) #为什么可以这样访问?
stu._Student__fun2()

print(dir(stu))

示例9-9属性的设置
class Student:
    def __init__(self, name,gender):
        self.name = name
        self.__gender = gender # self.__gender私有的实例属性

    #使用@property修饰方法,将方法转成属性使用
    @property
    def gender(self):
        return self.__gender

    #将gender这个属性设置为可写属性
    @gender.setter
    def gender(self,value):
        if value != '男' and value!='女':
            print('性别有误,已将性别默认设置为男')
            self.__gender = '男'
        else:
            self.__gender = value

stu=Student('陈玫玫','女')
print(stu.name,'的性别是',stu.gender)#stu.gender就会去执行stu.gender()

#尝试修改属性值
#stu.gender='男'#AttributeError: property 'gender' of 'Student' object has no setter

stu.gender='其他'
print(stu.name,'的性别是',stu.gender)

思考:在类外,私有实例属性要通过类进行调用,不可以直接调用,如果要直接调用应使用@property修饰方法,将方法转成属性使用,注意属性不能直接修改,要在类中通过setter更改(私有不可见)

2、继承

class 类名(父类1,父类2......,父类N)
          pass
点击查看代码
示例9-10继承
class Person: #默认继承了object
    def __init__(self, name,age):
        self.name = name
        self.age = age
    def show(self):
        print(f'大家好,我叫:{self.name},我今年:{self.age}岁')

#Student继承Person
class Student(Person):
    #初始化方法
    def __init__(self,name,age,stuno):
        super().__init__(name,age)#调用父类初始化方法为name和age赋值
        self.stuno = stuno

#Doctor继承Person类
class Doctor(Person):
    def __init__(self,name,age,department):
        super().__init__(name,age)
        self.department = department



#创建第一个子类
stu=Student('陈玫玫',20,'1001')
stu.show()
doctor=Doctor('张一一',32,'外科')
doctor.show()

示例9-11多继承
class FatherA():
    def __init__(self,name):
        self.name = name

    def showA(self):
        print('父类A中的方法')

class FatherB():
    def __init__(self,age):
        self.age = age

    def showB(self):
        print('父类B中的方法')

class Son(FatherA,FatherB):
    def __init__(self,name,age,gender):
        #需要调用两个父类的初始化方法
        FatherA.__init__(self,name)
        FatherB.__init__(self,age)
        self.gender = gender


son=Son('陈玫玫',20,'女')#调用Son类的__init__执行
son.showA()
son.showB()


点击查看代码
示例9-12方法重写
class Person: #默认继承了object
    def __init__(self, name,age):
        self.name = name
        self.age = age
    def show(self):
        print(f'大家好,我叫:{self.name},我今年:{self.age}岁')

#Student继承Person
class Student(Person):
    #初始化方法
    def __init__(self,name,age,stuno):
        super().__init__(name,age)#调用父类初始化方法为name和age赋值
        self.stuno = stuno

    def show(self):
        #调用父类show的方法
        super().show()
        print(f'我来自XXX大学,我的学号是{self.stuno}')

#Doctor继承Person类
class Doctor(Person):
    def __init__(self,name,age,department):
        super().__init__(name,age)
        self.department = department
    def show(self):
        #super().show()#调用父类show的方法
        print(f'大家好,我叫:{self.name},我今年{self.age}岁,我的工作科室是:{self.department}')



#创建第一个子类
stu=Student('陈玫玫',20,'1001')
stu.show()#调用子类自己的show方法
doctor=Doctor('张一一',32,'外科')
doctor.show()#调用子类自己的show方法

3、多态

点击查看代码
示例9-13多态
class Person():
    def eat(self):
        print('人,吃五谷杂粮')

class Cat():
    def eat(self):
        print('猫,喜欢吃鱼')

class Dog():
    def eat(self):
        print('狗,喜欢啃骨头')

#这三个类都有一个同名方法
#编写函数
def fun(obj):#obj是函数的形式参数,在定义处知道这个形参的数据类型吗?
    obj.eat()#通过变量obj()调用eat方法

#创建三个类的对象
per=Person()
cat=Cat()
dog=Dog()

#调用fun函数
fun(per) #Python中的多态,不关心对象的数据类型,只关心对象是否具有同名方法
fun(cat)
fun(dog)




object类

点击查看代码
示例9-14查看指定类的属性
class Person(object):
    def __init__(self, name,age):
        self.name = name
        self.age = age
    def show(self):
        print(f'大家好,我叫{self.name},我今年{self.age}岁')


#创建Person类的对象
per=Person('陈玫玫',20)#创建对象是会自动调用__init__方法
print(dir(per))

print(per)#自动调用了__str__方法

示例9-15__str__方法重写之前
class Person(object):
    def __init__(self, name,age):
        self.name = name
        self.age = age

#创建Person的对象
per=Person('陈玫玫',20)
print(per)
示例9-16__str__方法重写之后
class Person(object):
    def __init__(self, name,age):
        self.name = name
        self.age = age
    def __str__(self):
        return '这是一个人类,具有name和age两个实例属性' #返回值是一个字符串

#创建Person的对象
per=Person('陈玫玫',20)
print(per) #还是内存地址吗?不是,__str__方法中的内容  直接输出对象名,实际上是调用__str__方法
print(per.__str__()) #手动调用

点击查看代码
示例9-17特殊方法
a=10
b=20
print(dir(a))#Python中一切皆对象
print(a+b)#执行加法操作
print(a.__add__(b))
print(a.__sub__(b))#执行减法运算
print(f'{a}<{b}吗',a.__lt__(b))
print(f'{a}<={b}吗',a.__le__(b))
print(f'{a}={b}吗',a.__eq__(b))
print('-'*40)
print(f'{a}>{b}吗',a.__gt__(b))
print(f'{a}>={b}吗',a.__ge__(b))
print(f'{a}!={b}吗',a.__ne__(b))
print('-'*40)
print(a.__mul__(b))  #乘法
print(a.__truediv__(b))#除法
print(a.__mod__(b)) #取余
print(a.__floordiv__(b))#整除
print(a.__pow__(2))#幂运算


特殊属性

点击查看代码
示例9-18特殊属性
class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name = name
        self.age = age

#创建类的对象
a=A()
b=B()
#创建C类的对象
c=C('陈玫玫',20)
print('对象a的属性字典:',a.__dict__) #对象的属性字典
print('对象b的属性字典:',b.__dict__)
print('对象c的属性字典:',c.__dict__)


print('对象a所属的类:',a.__class__)
print('对象b所属的类:',b.__class__)
print('对象c所属的类:',c.__class__)

print('A类的父类元组',A.__bases__)
print('B类的父类元组',B.__bases__)
print('C类的父类元组',C.__bases__)


print('A类的父类',A.__base__)
print('B类的父类',B.__base__)
print('C类的父类',C.__base__) #A类,如果继承了N个父类,结果只显示第一个父类

print('A类的层次结构',A.__mro__)
print('B类的层次结构',B.__mro__)
print('C类的层次结构',C.__mro__) #C类继承了A类,B类,间接继承了object


#子类列表
print('A类的子类列表',A.__subclasses__())#A的子类是C类
print('B类的子类列表',B.__subclasses__())
print('C类的子类列表',C.__subclasses__()) #[]



类的深拷贝与浅拷贝‘

点击查看代码
示例9-19类的深拷贝与浅拷贝
import copy


class CPU():
    pass
class Disk():
    pass
class Computer():
    #计算机使用cpu和硬盘组成
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk


cpu=CPU()#创建了一个CPU对象
disk=Disk()#创建了一个硬盘对象
#创建一个计算机对象
com=Computer(cpu,disk)
#变量(对象)的赋值
com1=com
print(com,'子对象的内存地址:',com.cpu,com.disk)
print(com1,'子对象的内存地址:',com1.cpu,com1.disk)


#类的浅拷贝
print('-'*40)
com2=copy.copy(com)#com2是新产生的对象,com2的子对象cpu和disk不变
print(com,'子对象的内存地址:',com.cpu,com.disk)
print(com2,'子对象的内存地址:',com2.cpu,com2.disk)


#类的深拷贝
print('-'*40)
com3=copy.deepcopy(com)#com3是新产生的对象,com3的子对象cpu和disk也会重新创建
print(com,'子对象的内存地址:',com.cpu,com.disk)
print(com3,'子对象的内存地址:',com3.cpu,com3.disk)



点击查看代码
实战一
#我的思路
class Circle():
    def __init__(self, r):
        self.r = r

    def get_area(self):
        area =3.14 * self.r ** 2
        print('圆的面积为',area)

    def get_perimeter(self):
        perimeter = 2 *3.14*self.r
        print('圆的周长为', perimeter)

r= int(input('请输入圆的半径:'))
cir=Circle(r)
cir.get_area()
cir.get_perimeter()


print('-'*50)
#老师思路
class Circle():
    def __init__(self, r):
        self.r = r
    #计算面积的方法
    def get_area(self):
      #return 3.14*self.r**2
       return 3.14*pow(self.r,2)

    #计算圆的周长
    def get_perimeter(self):
        return 2*3.14*self.r

#创建对象
r=eval(input('请输入圆的半径:'))
c=Circle(r)
#调用方法
area=c.get_area()
perimeter=c.get_perimeter()
print('圆的面积为:',area)
print('圆的周长为:',perimeter)


点击查看代码
#我的思路
class Student():
    def __init__(self, name, age,gender, score):
        self.name = name
        self.age = age
        self.gender = gender
        self.score = score


    def info(self):
        print(f'姓名为:{self.name}, 年龄为:{self.age}, 性别为:{self.gender},得分为: {self.score}')


print('请输入5位学生信息:(姓名#年龄#性别#成绩)')
lst=[]
new_lst=[]
for i in range(5):
    stu=input(f'请输入第{i+1}位学生信息:')
    lst.append(stu)
    s= lst[i].split('#')
    new_lst.append(s)

for i in range(0,len(new_lst)):
    stu1=Student(new_lst[i][0],new_lst[i][1],new_lst[i][2],new_lst[i][3])
    stu1.info()

print('-'*50)



#老师思路
class Student():
    def __init__(self, name, age,gender, score):
        self.name = name
        self.age = age
        self.gender = gender
        self.score = score


    def info(self):
        print(self.name,self.age,self.gender,self.score)


print('请输入5位学生信息:(姓名#年龄#性别#成绩)')
lst=[]#用于存储5个学生对象
for i in range(1,6):
    s=input(f'请输入第{i}位学生信息:')
    s_lst=s.split('#') #索引为0是姓名,索引为1是年龄,索引为2是性别,索引为3是成绩
    #创建学生对象
    stu=Student(s_lst[0],s_lst[1],s_lst[2],s_lst[3])
    #将学生对象添加到列表中
    lst.append(stu)

#遍历列表,调用学生对象的info方法
for item in lst: #item的数据类型是Student类型
    item.info() #对象名.方法名()


点击查看代码
实战三


class Instrument():
    def make_sound(self):
        pass


class Erhu(Instrument):
    def make_sound(self):
        print('二胡在演奏')

class Piano(Instrument):
    def make_sound(self):
        print('钢琴在演奏')

class Violin(Instrument):
    def make_sound(self):
        print('小提琴在演奏')

#编写一个函数
def play(obj):
    obj.make_sound()


#测试
er=Erhu()
piano=Piano()
vio=Violin()


#调用方法
play(piano)
play(vio)
play(er)


点击查看代码
实战四
#我的思路
class Car():
    def __init__(self,car_model,license_plate):
        self.car_model=car_model
        self.license_plate=license_plate

    def start(self):
        pass

    def stop(self):
        pass

class Taix(Car):
    def __init__(self,car_model,license_plate,company):
        self.company=company
        super().__init__(car_model, license_plate)

    def start(self):
        print('乘客您好!')
        print(f'我是{self.company}出租车公司的,我的车牌号是{self.license_plate},您要去哪里?')

    def stop(self):
        print('目的地到了,请您付款下车,欢迎下次乘坐')


class PrivateCar(Car):
    def __init__(self,car_model,license_plate,carname):
        self.carname=carname
        super().__init__(car_model, license_plate)

    def start(self):
        print(f'我是{self.carname},我的汽车我做主')

    def stop(self):
        print('目的地到了,我们去玩吧')

ta=Taix('计程车','京A88888','长城')
ta.start()
ta.stop()
print('-'*50)
pri=PrivateCar('面包车','云A4564','武大郎')
pri.start()
pri.stop()

#老师的思路
class Car():
    def __init__(self,type,no,):
        self.type = type
        self.no = no

    def start(self):
        print('我是车,我能启动')

    def stop(self):
        print('我是车,我能停止')


#出租车
class Taxi(Car):
    def __init__(self,type,no,company):
        super().__init__(type,no)
        self.company = company
    #重写父类的启动与停止
    def start(self):
        print('乘客您好!')
        print(f'我是{self.company}出租车公司的,我的车牌号是{self.no},您要去哪里?')

    def stop(self):
        print('目的地到了,请您付款下车,欢迎下次乘坐')


class Family(Car):
    def __init__(self,type,no,name):
        super().__init__(type,no)
        self.name = name

    def start(self):
        print(f'我是{self.name},我的汽车我做主')

    def stop(self):
         print('目的地到了,我们去玩吧')

#测试
taix=Taxi('上海大众','京A88888','长城')
taix.start()
taix.stop()
print('-'*50)
family_car=Family('广汽丰田','京B66666','武大郎')
family_car.start()
family_car.stop()

标签:__,name,第九章,self,面向对象,print,程序设计,age,def
From: https://www.cnblogs.com/pl-blog1/p/18312395

相关文章

  • TypeScript与面向对象编程
    引言TypeScript简介TypeScript是JavaScript的一个超集,由微软开发,它在JavaScript的基础上添加了类型系统和对ES6+的新特性的支持。TypeScript最终会被编译成纯JavaScript代码,以便在任何支持JavaScript的环境中运行。面向对象编程(OOP)概念面向对象编程是一种编程范式,它使用“......
  • 面向对象设计的原则有哪些?
    1、单一责任原则(SingleResponsibilityPrinciple,SRP)一个类应该仅有一个引起它变化的原因。换句话说,一个类应该只有一个职责。这有助于保持类的内聚性,降低耦合度。2、开放-封闭原则(Open-ClosePrinciple,OCP)软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改的。......
  • Python第九章(面向对象基础--属性,继承,dir查看,内存地址,权限等等和银行账户题目,圆的面积
    面向对象创造对象示例代码:类的名字用小驼峰命名法#编写Person类classPerson():passclassCat:#,小括号可以省略pass#对象名=类名per=Person()c=Cat()#小括号不能省略print(type(per))print(type(c))代码结果:<class'__main__.Person'><class'__mai......
  • 模块1 课程准备 --- 第三章:建立面向对象的编程思想
    第三章建立面向对象的编程思想主要知识点:1、理解面向对象编程的基本思想。2、掌握面向对象编程的一般方法。3、能够运用Java语言编写简单的应用程序。学习目标:掌握面向对象编程的基本思想解释:面向过程编程从解决每一个步骤入手,适合于解决比较小的简......
  • 使用面向对象思想实现乐器弹奏
    题目乐手可以弹奏不同的乐器从而发出不同的声音。可以弹奏的乐器包括二胡、钢琴和琵琶。定义乐器类Instrument,包括方法make_sound()。定义乐器类的子类:二胡Erhu、钢琴Piano和小提琴Violin,定义一个函数可以弹奏各种乐器play(instrument),测试给乐手不同的乐器让他弹奏。代码c......
  • 【Java面向对象】异常处理
    文章目录1.异常1.1异常类1.2异常类型1.3免检异常和必检异常2.异常的声明、抛出与捕获2.1声明异常2.2抛出与捕获异常2.3从异常中获取信息3.链式异常3.1重新抛出异常3.2链式异常4.创建自定义异常类1.异常1.1异常类异常是对象,而对象都采用类来定义。异常的......
  • C++面向对象三大特性:继承
     前言:众所周知,C++作为一个面向对象的编程语言,有着三大特性:封装,继承,和多态。在前面的C++学习中,我们大部分所接触的只有封装,现在,就让我们来认识一下继承吧。一、继承的概念继承是指一个类(子类)从另一个类(父类)获得属性和行为的过程,它是使得代码得到复用的重要手段,允许程序员......
  • Java面向对象程序三大特性:封装、继承、多态
    目录 引言一.封装二.继承三.多态四.结论 引言 在现代软件开发中,面向对象编程(OOP)已成为一种流行且有效的编程范式,其中Java语言以其高效性和灵活性深受开发者的喜爱。面向对象编程的核心在于其三大特性:封装、继承和多态。这些特性不仅提高了代码的重用性和可维......
  • C++面向对象编程的一个核心概念--RAII
    RAII是"ResourceAcquisitionIsInitialization"(资源获取即初始化)的缩写,它是C++编程中的一种编程技术,用于管理资源的生命周期。RAII是C++面向对象编程的一个核心概念,它利用对象的构造函数和析构函数来自动管理资源,如内存、文件句柄、线程、互斥锁等。RAII的主要原则包括:1.*......
  • 面向对象05-抽象类 / 接口 / 内部类
    一、抽象类1.abstract修饰的方法/类  publicabstractvoidwork();2.方法体中没有东西,子类必须重写(统一)3.类中有抽象方法,这个类必须也为抽象类4.注意事项: (1)抽象类不能实例化(实例化:创建对象) (2)抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类 (3)可以有构......