版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目六面
向
对
象
编
程项目六
Python是真正面向对象的高级动态编程语言,它以类和对象作为面向对象编程的基础,具有封装、继承和多态三大基本特性,能够很好地支持代码复用和设计复用,使得代码具有更好的可读性和可扩展性。本项目将详细介绍Python中面向对象编程的方法。项目导读项目六理解面向对象程序设计思想。掌握定义类和创建对象的方法,self参数、构造方法和析构方法的使用方法。理解类变量和实例变量、类方法和静态方法的区别。掌握面向对象的三大特性(封装、继承和多态)及相关知识的使用方法。能使用面向对象方法编写程序。学习目标思政目标提高对事物的观察和归纳能力。
了解生物多样性的重要性,增强保护生态环境意识。项目六增强使用抽象思维解决实际问题的能力。Content项目六开发动物园里有什么游戏制作个人信息调查表开发猫狗大战游戏开发“动物园里有什么”游戏任
务
一任务一
“动物园里有什么”游戏想要实现的功能是轮流说出一种动物的种类及叫声,如果该动物在预先规定的范围中,则输出动物的种类及叫声,否则终止游戏。本任务将带领大家利用类和对象,开发“动物园里有什么”游戏。开发“动物园里有什么”游戏任务描述知识链接一、面向对象的程序设计传统的程序设计方法被称为面向过程的程序设计。面向过程程序设计的核心是过程,即解决问题的步骤。面向过程的设计就好比设计一条流水线,需要考虑周全解决问题的每个步骤,如果中间有某个环节发生了变化,那么就得重新设计流水线。因此,使用这种方法开发的程序重用性差、难于维护。在这种情况下,面向对象程序设计诞生了。面向对象程序设计(objectorientedprogramming,OOP)是将所有预处理的问题抽象为对象,并将相应的属性和行为封装起来,以提高软件的重用性、灵活性和扩展性。现实世界中,对象就是客观存在的某一事物,如一个人、一辆自行车等。而面向对象的编程世界中,对象具有属性和行为两个特征,每个对象都有各自的属性和行为。而类是对这些具有共同特征的对象的概括、归纳和抽象表达。例如,将人抽象为“人”类,它具有名字、性别等属性,行走、吃饭等行为,那么具体的名字为“小明”“小红”的个体就是“人”类的对象,具体关系如图6-1所示。任务一图6-1类和对象的关系class类名:类体Python中定义类的语法格式如下。二、类的定义任务一其中,class是Python的关键字,用于声明类;类名必须是合法标识符,通常是一个有意义的名称;类体定义类的内部实现,一般包括变量和方法的定义。定义类时应注意以下几点。(1)类名的首字母一般需要大写,如Car。(2)类名后必须紧跟冒号。(3)类体相对于class关键字必须保持一定的空格缩进。例如,定义一个Person类,包含姓名属性和说话行为,可以用下面代码实现。任务一classPerson: #定义Person类name='小蓝' #定义姓名变量defspeak(self): #定义说方法print('大家好!')在上述代码中,使用class定义了一个名为Person的类,类中有一个name变量和一个speak()方法。从代码中可以看出,方法的定义格式和函数是一样的,主要区别在于,方法必须显式地声明一个self参数,且须位于参数列表的开头。对象名=类名()Python中创建对象的语法格式如下。三、创建对象任务一创建对象后,可以使用它来访问类中的变量和方法,其语法格式如下对象名.变量名对象名.方法名([参数])任务一【例
6-1】创建对象,访问类中的变量和方法。【参考代码】classPerson: #定义Person类name='小蓝' #定义姓名变量defspeak(self): #定义说方法print('大家好!')person=Person() #创建对象person.speak() #调用类中的方法print('我是{}'.format())
#访问类中的变量任务一【运行结果】程序运行结果如图6-2所示。图6-2
例6-1程序运行结果在Python中,一个类可以生成无数个对象,当一个对象的方法被调用时,对象会将自身的引用作为第一个参数(即方法的self参数),传递给该方法。这样,Python就知道需要操作哪个对象的方法了。带self参数的方法也称作实例方法,在类的实例方法中访问实例变量时,须以self为前缀,但在外部通过对象名调用实例方法时不需要传递该参数。四、self参数任务一任务一【例
6-2】self参数的使用。【参考代码】classPerson: #定义Person类defnamed(self,name): #定义命名的方法=name #赋值defspeak(self): #定义显示名字的方法print('我的名字是{}'.format()) #输出名字xiaolan=Person() #创建对象xiaoland('小蓝') #xiaolan调用named()方法xiaowu=Person() #创建对象xiaowud('小舞') #xiaowu调用named()方法xiaolan.speak() #xiaolan调用speak()方法xiaowu.speak() #xiaowu调用speak()方法任务一【运行结果】程序运行结果如图6-3所示。图6-3例6-2程序运行结果任务一
Python在类中定义方法时将第一个参数命名为self只是一个习惯,而实际上名称是可以改变的。例如:
classA:
defshow(my):
print('hello!')
a=A()
a.show()
上述代码中,将show()方法的第一个参数命名为my,程序运行结果为“hello!”。构造方法的固定名称为__init__(),当创建类的对象时,系统会自动调用构造方法,实现对象的初始化操作。五、构造方法任务一【例
6-3】构造方法示例。【参考代码】classPerson: #定义Person类#构造方法,定义变量并赋初值def__init__(self):='小蓝'self.snack='薯条'defeat(self): #定义方法,输出变量print('{}喜欢的零食是{}'.format(,self.snack))xiaolan=Person() #创建对象xiaolan.eat() #调用eat()方法任务一【运行结果】程序运行结果如图6-4所示。图6-4例6-3程序运行结果【程序说明】在该程序中,第3~5行实现了__init__()方法,给Person类添加了name和snack属性并赋初值,在eat()方法中访问了name和snack的值。例6-3中,无论创建多少个Person类的对象,name和snack变量的初始值都是默认值。如果想要为不同对象初始化不同的值,可使用有参构造方法,即在构造方法中设置形参。创建对象时,为不同对象传入不同的实参,并将每个对象的变量初始化为实参的值。任务一【例
6-4】有参构造方法示例。【参考代码】classPerson: #定义Person类#构造方法,定义变量并赋初值def__init__(self,name,snack):=nameself.snack=snackdefeat(self): #定义方法,输出变量print('{}喜欢的零食是{}'.format(,self.snack))xiaolan=Person('小蓝','薯条')
#创建对象xiaolanxiaolan.eat()
#xiaolan调用eat()方法xiaowu=Person('小舞','冰激凌')
#创建对象xiaowuxiaowu.eat()
#xiaowu调用eat()方法任务一【运行结果】程序运行结果如图6-5所示。图6-5例6-4程序运行结果【程序说明】在该程序中,第3~5行定义了带参数的构造方法,包含两个参数name和snack,创建对象时,可为不同对象传入不同的参数值。Python中每个类有且仅有一个构造方法,即便不手动为类添加任何构造方法,创建对象时,也会隐式地调用只包含self参数的构造方法。创建对象时,Python解释器会默认调用构造方法;当需要删除一个对象来释放其所占的资源时,Python解释器会调用析构方法。析构方法的固定名称为__del__(),程序结束时会自动调用该方法,也可以使用del语句手动调用该方法删除对象。六、析构方法任务一【例
6-5】比较下面两个程序,分析输出结果。【代码一】classPerson():def__init__(self): #构造方法print('---调用构造方法创建对象---')def__del__(self): #析构方法print('---调用析构方法删除对象---')person=Person() #创建对象print('---程序结束---')任务一【代码二】classPerson():def__init__(self): #构造方法print('---调用构造方法创建对象---')def__del__(self): #析构方法print('---调用析构方法删除对象---')person=Person() #创建对象delperson #删除对象print('---程序结束---')【运行结果】图6-6代码一运行结果图6-7代码二运行结果任务一【程序说明】以上两段代码的区别在于:代码二在程序结束前使用del语句手动调用析构方法删除对象,因此,先输出“---调用析构方法删除对象---”;而代码一没有使用del语句,因此,在程序结束时才调用析构方法,后输出“---调用析构方法删除对象---”。任务实施完成本任务,须首先定义动物类,然后循环输入动物的种类及叫声,判断是否在指定列表中,具体实现步骤如下。(1)定义动物类Animal,包含动物种类(species)和叫声(sound)等变量,以及构造方法和叫方法speak()。其中,构造方法判断传入的动物种类参数是否在指定列表中,如果在列表中,species和sound赋值为传入的参数,否则赋值为None;speak()方法判断species是否为None,如果是,提示游戏结束,并返回False,否则输出species和sound的值,并返回True。(2)定义循环标志flag,初始值为True。在循环中,输入动物的种类和叫声(使用空格隔开),并分割输入的字符串,返回一个列表;然后以列表的元素作为参数创建对象;最后调用speak()方法,将返回值赋给flag。制作个人信息调查表任
务
二
个人信息调查表可根据调查目的统计个人的相关信息,如居住城市、姓名、年龄、爱好和常用的App等,用于人群数据分析。本任务将带领大家编写Python程序,使用类变量和实例变量,制作个人信息调查表。任务二制作个人信息调查表任务描述知识链接
一、类变量和实例变量Python类中定义的变量包括两种:类变量和实例变量,它们有以下两点区别。(1)类变量是在类中所有方法外定义的;实例变量一般是指在构造方法__init__()中定义的,在类中定义和使用时必须以self作为前缀。任务二与很多面向对象程序设计语言不同,Python允许在类外部动态地为类和对象增加变量,这是Python动态类型特点的重要体现。(2)类变量属于类,可以通过类名或对象名访问;而实例变量属于实例(即对象),在主程序中(或类的外部)只能通过对象名访问。任务二【例
6-6】类变量和实例变量示例。【参考代码】classToy: #定义Toy类type='小车' #初始化类变量def__init__(self,color):self.color=color #初始化实例变量toy=Toy('红色') #创建对象#访问类变量和实例变量并输出print(Toy.type,toy.type,toy.color)Toy.wheelNum=4 #增加类变量toy.price=5 #增加实例变量#访问增加的类变量和实例变量并输出print(Toy.wheelNum,toy.wheelNum,toy.price)任务二【运行结果】程序运行结果如图6-9所示。图6-9例6-6程序运行结果【程序说明】Toy类中定义的type和动态为类增加的wheelNum都为类变量,因此,它们都属于类,可以通过类名或对象名访问。但构造方法中定义的color和动态为对象toy增加的price都为实例变量,因此,它们只能通过对象名访问,如果用类名进行访问会提示错误信息。例如,在程序的末尾增加一条语句“print(Toy.color)”,程序运行出错,提示Toy对象没有color属性,运行结果如图6-10所示。任务二如果类中有相同名称的类变量和实例变量,通过对象名访问变量时获取的是实例变量的值,通过类名访问变量时获取的是类变量的值。图6-10错误提示任务二【例
6-7】类中有相同名称的类变量和实例变量示例。【参考代码】classToy: #定义Toy类color='白色' #初始化类变量def__init__(self):self.color='红色' #初始化实例变量toy=Toy() #创建对象print(Toy.color,toy.color)
#访问类变量和实例变量并输出任务二【运行结果】程序运行结果如图6-11所示。图6-11例6-7程序运行结果【程序说明】从程序运行结果可以看出,类变量和实例变量的名称相同,都为color,通过类名Toy访问color(Toy.color)时获取的是类变量的值“白色”,而通过对象名toy访问color(toy.color)时获取的是实例变量的值“红色”。任务二二、类方法和静态方法1.类方法类方法是类所拥有的方法,须用修饰器“@classmethod”来标识。对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(同self一样只是一个习惯),可以通过对象名调用类方法,也可以通过类名调用类方法。【例
6-8】类方法示例。【参考代码】任务二classBook: #定义Book类type='课外书' #定义类变量并赋值#类方法,用classmethod进行修饰@classmethoddefgetType(cls):returncls.type #返回类变量的值book=Book() #创建对象print(Book.getType()) #通过类名调用类方法print(book.getType()) #通过对象名调用类方法任务二【运行结果】程序运行结果如图6-12所示。图6-12例6-8程序运行结果【程序说明】上述代码中定义了一个Book类,在其中添加了类变量type,然后在类方法getType()中返回type的值。从运行结果可以看出,用对象名调用类方法和用类名调用类方法的效果是一样的。类方法可以访问类变量,但无法访问实例变量。任务二二、类方法和静态方法2.静态方法要在类中定义静态方法,须在方法前加上“@staticmethod”标记符,以表示下面的方法是静态方法。使用静态方法的好处是,不需要实例化对象即可调用该方法。静态方法没有self参数,所以它无法访问类的实例变量;静态方法也没有cls参数,所以它也无法访问类变量。静态方法既可以通过对象名调用,也可以通过类名调用。【例
6-9】静态方法示例。【参考代码】任务二classBook: #定义Book类type='课外书' #定义类变量并赋值#静态方法,用@staticmethod进行修饰@staticmethoddefprintType():print('---书的类别---')book=Book() #创建对象book.printType() #通过对象名调用静态方法Book.printType() #通过类名调用静态方法print(book.type) #输出type任务二【运行结果】程序运行结果如图6-13所示。图6-13例6-9程序运行结果通过类的对象名可以调用实例方法、类方法和静态方法,通过类名可以调用类方法和静态方法。一般情况下,如果要修改实例变量的值,可直接使用实例方法;如果要修改类变量的值,可直接使用类方法;如果是辅助功能,如打印菜单等,则可以考虑使用静态方法。任务实施完成本任务,须首先定义人类Person,包含居住城市(city)、姓名(name)、年龄(age)、爱好(hobby)和常用的App(app)等变量,以及构造方法、printMenu()方法和printInfo()方法。其中,city为类变量,初始值为“北京”,其余为实例变量;构造方法初始化实例变量;printMenu()为静态方法,输出个人信息提示;printInfo()方法输出个人信息。然后创建两个对象person1和person2,分别调用printMenu()和printInfo()方法,创建person2前将city重新赋值为“上海”。开发“猫狗大战”游戏任
务
三
“猫狗大战”游戏想要实现的功能是通过键盘控制猫和狗游戏角色进行PK,可控制动物角色增加生命值,或者攻击对方,对方受到攻击会减少一定的生命值,直到一方的生命值为零结束比赛。本任务将带领大家利用类的继承,开发“猫狗大战”游戏。任务三开发“猫狗大战”游戏任务描述知识链接
面向对象编程具有封装、继承和多态三大特征。一、封装封装是面向对象编程的核心思想,它将对象的属性和行为封装起来(其载体是类),隐藏其实现细节,用户只需通过接口来操作对象。好比用户使用计算机时,通过键盘就可以实现一些功能,无须知道计算机内部是如何工作的。任务三【例
6-10】私有化变量和方法。【参考代码】classPeople:
#定义People类def__init__(self,name,age):=nameself.__age=age #定义私有变量__agedef__sayHello(self):
#定义私有方法print('Hello,大家好')defgreeting(self):
#定义接口函数,调用私有方法self.__sayHello()defgetAge(self):
#定义接口函数,返回私有变量__age的值returnself.__agexiaolan=People('小蓝',10)
#创建对象xiaolan.greeting() #调用接口函数#访问实例变量和调用接口函数并输出print('我叫{},今年{}岁了。'.format(,xiaolan.getAge()))任务三【运行结果】程序运行结果如图6-15所示。图6-15例6-10程序运行结果如果在类外部调用私有方法或访问私有变量,就会提示错误信息。例如,在程序的末尾增加两条语句“xiaolan.__sayHello()”和“print(xiaolan.__age)”,程序运行出错,结果如图6-16所示。出现上述问题的原因是“__sayHello()”为私有方法,类的外部无法调用类的私有方法。同理,如果程序执行到“print(xiaolan.__age)”时,也会提示类似的错误信息。任务三图6-16错误提示Python目前的私有机制其实是伪私有,实际上,在外部可以通过“_类名__属性”访问私有变量和调用私有方法。例如,将例6-10代码中的最后两条语句改成以下形式,也可正常运行程序。xiaolan._People__sayHello() #类外部调用私有方法#类外部访问私有变量print('我叫{},今年{}岁了'.format(,xiaolan._People__age))任务三二、继承继承是面向对象程序设计中两个类之间的一种关系,是指从已有的类中派生出新的类。被继承的类称为基类或父类,继承父类的类称为子类或派生类。子类可以继承父类的属性和行为,还可以增加自己的属性和行为。例如,自行车类有品牌、外观等属性,刹车、加速等行为,而双人自行车继承了自行车类(父类)的属性和行为,还增加了后座这个属性。子类还可以改变从父类继承来的行为。例如,杂技演员使用的自行车不仅可以前进,还可以后退,这就改变了自行车类的行为。继承使父类的代码得到重用,在继承父类提供的共同特性的基础上增加新的代码,可以大幅度减少开发工作量,并且可以很大程度地保证质量。继承分为单继承和多继承两种。在Python中,当一个子类只有一个父类时称为单继承。定义子类的语法格式如下子类可以继承父类的所有公有变量和公有方法,但不能继承其私有变量和私有方法。class子类名(父类名):任务三【例
6-11】单继承示例。【参考代码】classAnimal: #定义Animal类type='动物' #定义变量typefood='食物' #定义变量fooddefeat(self):
#定义方法输出type和foodprint('{}吃{}'.format(self.type,self.food))classCat(Animal):
#定义Cat类继承Animal类pass #空语句cat=Cat() #创建对象cat.eat() #调用父类方法cat.type='猫' #修改typecat.food='鱼' #修改foodcat.eat() #调用父类方法任务三【运行结果】程序运行结果如图6-17所示。图6-17例6-11程序运行结果【程序说明】上述代码中定义了Animal类,包含type和food变量,以及eat()方法;然后定义了Cat子类继承Animal类,不执行任何操作;最后创建Cat类对象,修改父类中的变量,并调用父类中的方法。从程序的运行结果可以看出,子类继承了父类的变量和方法。Python中pass表示空语句,即不执行任何操作,一般用作占位语句,保持程序结构的完整性。任务三2.多继承
多继承指一个子类可以有多个父类,它继承了多个父类的特性。例如,沙发床是沙发和床的功能的组合,儿子喜欢做爸爸和妈妈喜欢做的事。多继承可以看作是对单继承的扩展,其语法格式如下。class子类名(父类名1,父类名2……):【例
6-12】多继承示例。任务三classDadLikeDo: #定义DadLikeDo类defbasketball(self): #定义打篮球方法print('打篮球')classMomLikeDo: #定义MomLikeDo类defsing(self): #定义唱歌方法print('唱歌')#定义SonLikeDo类,继承DadLikeDo类和MomLikeDo类classSonLikeDo(DadLikeDo,MomLikeDo):defdance(self): #定义跳舞方法print('跳舞')son=SonLikeDo() #创建对象print('儿子喜欢做的事:')son.basketball() #调用DadLikeDo类的方法son.sing() #调用MomLikeDo类的方法son.dance() #调用SonLikeDo类的方法【参考代码】任务三【运行结果】程序运行结果如图6-18所示。图6-18例6-12程序运行结果【程序说明】上述代码中定义了DadLikeDo类,包含basketball()方法,以及定义了MomLikeDo类,包含sing()方法;然后定义了继承DadLikeDo类和MomLikeDo类的子类SonLikeDo,包含dance()方法;最后创建SonLikeDo类的对象,分别调用basketball()、sing()和dance()方法。从程序运行结果可以看出,子类同时继承了多个父类的方法。任务三在Python中,如果两个父类中有同名的方法,那么调用该同名方法时会调用先继承的类中的方法。例如,如果DadLikeDo类和MomLikeDo类中有同名的方法,用“classSonLikeDo(DadLikeDo,MomLikeDo):”语句定义子类时,子类会先继承DadLikeDo类。任务三3.方法重写
当父类中的方法无法满足子类需求或子类具有特有功能时,可以在子类中重写父类的方法,即子类中的方法会覆盖父类中同名的方法,以实现不同于父类的功能。【例
6-13】重写父类的方法示例。任务三classStudent: #定义Student类name='xx' #定义变量namedefcategory(self): #定义方法category()print(+'是学生')classPupil(Student): #定义Pupil类继承Student类defcategory(self): #重写category()方法print(,'是小学生')classJunior(Student): #定义Junior类继承Student类defcategory(self): #重写category()方法print(,'是初中生')xioalan=Pupil() #创建Pupil类对象='小蓝' #修改namexioalan.category() #调用category()方法xiaoming=Junior() #创建Junior类对象='小明' #修改namexiaoming.category() #调用category()方法【参考代码】任务三【运行结果】程序运行结果如图6-19所示。图6-19例6-13程序运行结果【程序说明】从程序运行结果可以看出,在调用Pupil类和Junior类对象的category()方法时,只调用了子类中重写的方法,不会再调用父类的category()方法。如果需要在子类中调用父类的方法,可以使用内置函数super()或通过“父类名.方法名()”来实现。任务三classStudent:
#定义Student类def__init__(self,name,age):
#构造方法,传递name和age=nameself.age=agedefshowInfo(self):
#定义showInfo()方法,输出name和ageprint('姓名:{};年龄:{}'.format(,self.age))classPupil(Student):
#定义Pupil类继承Student类#构造方法,传递name、age和sexdef__init__(self,name,age,sex):super().__init__(name,age)
#调用父类构造方法self.sex=sexdefshowInfo(self):Student.showInfo(self)
#调用父类showInfo()方法print('性别:{}'.format(self.sex))#输出sexxiaolan=Pupil('小蓝',10,'女')
#创建对象xiaolan.showInfo()
#调用showInfo()方法【例6-14】子类调用父类的方法示例。【参考代码】任务三【运行结果】程序运行结果如图6-20所示。图6-20例6-14程序运行结果【程序说明】以上代码中定义了Student类,在该类的__init__()方法中定义了name和age变量。然后定义了继承Student类的子类Pupil,在该类中重写了构造方法__init__(),使用super()函数调用父类的构造方法,并添加了自定义变量sex,使Pupil类既拥有自定义的sex,又拥有父类的name和age;还重写了showInfo()方法,使用父类名调用了父类的showInfo()方法输出name和age,又输出了sex。任务三三、多态
在Python中,多态指的是一类事物有多种形态,如一个父类有多个子类,因而多态的概念依赖于继承。而多态性可以这样描述:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应同一消息(调用函数)。【例6-15】多态示例。任务三classPerson: #定义Person类def__init__(self,name):
#构造方法,定义name=namedefwho(self): #定义who()方法print('我是一个人,我的名字是{}'.format())classStudent(Person):
#定义Student类,继承Person类def__init__(self,n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 女工个人年度工作总结
- 外联部部长竞选演讲稿(15篇)
- 家风家训故事演讲稿
- 顽固性心力衰竭患者的个案护理
- 2026年托福阅读口语真题
- 公司审计准备管理办法
- 2026年养老机构防噎食管理制度规范
- 岗位职位说明书和岗位职责描述市场总监
- 2026年中级会计职称《中级会计实务》考前密押卷
- 2025年资产评估师《资产评估实务二》考试真题(完整版)
- 学位英语4000词(开放大学)
- GB/T 9799-2024金属及其他无机覆盖层钢铁上经过处理的锌电镀层
- 中医是怎样治疗动脉硬化的
- 产品漏装改善报告
- 悬挑式卸料平台监理实施细则
- 铸件(原材料)材质报告
- 提货申请单表
- 脑与认知科学概论PPT(第2版)完整全套教学课件
- 【初中化学】中国化学家-李寿恒
- 生管指导手册(什么是PMC)
- 历届全国初中数学联赛真题和答案
评论
0/150
提交评论