Python廖雪峰教程学习笔记:Day9

本文深入讲解Python中的面向对象编程(OOP)概念,包括如何通过私有属性保护对象状态,使用get和set方法控制访问,以及如何实现继承和多态。通过具体示例,读者将学会如何设计更安全、更灵活的类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

养成一个好的习惯只需要坚持21天,Day9

访问限制

由上一节定义的Student类来看,我们可以在外部代码修改name、score属性。比如我们想要修改对象的成绩,可以直接对score赋值。

bart.score = 60
print(bart.score)
# 60

如果要让内部的属性不被外部访问和修改,我们可以在属性的名称前面加上两个下划线__,这样就变成了一个私有对象,只有内部可以访问,外部不可以访问。即在外部即不能访问也不能进行修改。

class Student(object):
	
	def __init__(self,name,score):
		self.__name = name
		self.__score = score
	def print_score(self):
		print('%s: %s' % (self.__name, self.__score))
bart  = Student('Bart Simpon',99)

在外部访问实例变量的属性:

bart.__name
# ---------------------------------------------------------------------------
# AttributeError                            Traceback (most recent call last)
# <ipython-input-2-b54cbc8ec6d2> in <module>()
# ----> 1 bart.__name

#AttributeError: 'Student' object has no attribute '__name'

这样确保了外部代码不能随便的改变对象内部的状态,如果在限制访问的同时想要允许外部代码进行访问或者修改的话,就可以给类增加getset方法。

class Student(object):
	...
	# get方法,获取对象的name、score属性
	def get_name(self):
		return self.__name
	def get_score(self):
		return self.score
	
	# set方法,改变对象的name、score属性
	def set_name(self,name):
		self.__name = name
	def set_score(self,score):
		if 0 <=score<= 100:
			self.__score = score
		else:
			 raise ValueError('bad score')

在Python中,类似__xxx__的变量是特殊变量,特殊变量在外部是可以访问的,不是私有变量。有时候我们会看到一个下划线开头的变量名,比如_name,这样命名的意思是“虽然我可以被访问,但是请把我视为私有变量,不要随意访问。”
双线划线开头的变量也不是一定不能访问,而是不能直接访问,如果使用baer._Student__name来访问也可以等到name变量。

bart._Student__name
# 'Bart Simpson'

练习
请把下面的Student对象的gender字段对外隐藏起来,用get_gender()和set_gender()代替,并检查参数有效性:

class Student(object):
    def __init__(self, name, gender):
        self.name = name
        self.__gender = gender
    def get_gender(self):
        return self.__gender
    def set_gender(self,gender):
        if gender in ('male','female'):
            self.__gender = gender
        else:
            raise ValueError('bad gender')
# 测试:
bart = Student('Bart', 'male')
if bart.get_gender() != 'male':
    print('测试失败!')
else:
    bart.set_gender('female')
    if bart.get_gender() != 'female':
        print('测试失败!')
    else:
        print('测试成功!')
# 测试成功!

继承和多态

在OOP程序设计中,当我们定义一个class类时,我们可以从已有的class继承,新的class类成为子类(Subclass),原有的class称为父类(Base class)。
首先,我们编写一个animal类,使用run()方法直接打印:

class Animal(object):
	def run(self):
		print('Animal is running...')

继续编写DogCat类时,就可以直接从Animal类继承,把Animal写在类名后面的括号里,就代表Dog继承Animal类,Cat同理:

class Dog(Animal)pass
class Cat(Animal):
	pass

继承之后,子类获得了父类的全部功能。在此处,DogCat类就继承了Animal类的run()方法。

dog = Dog()
dog.run()
cat = Cat()
cat.run()
# Animal is running...
# Animal is running...

接着对子类增加一些方法:

class Dog(Animal):
	def run(self):
		print('Dog is running...')
		
class Cat(Animal):
    def run(self):
        print('Cat is running...')

对子类增加方法后执行:

dog = Dog()
dog.run()
cat = Cat()
cat.run()
# Dog is running...
# Cat is running...

虽然子类继承的父类中也有run()方法,但是子类的run()覆盖了父类的run(),这就是继承的多态表现。要判断一个变量是否是某个类型可以使用isinstance()判断:

b = Dog()
isinstance(b,Dog)
# true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值