我们在编程时思考的不是程序的执行流程,而是对象(即学生)
学生们都有什么共同的属性(property)?
字典里的姓名(name)和分数(score)都是学生的属性打印学生的成绩:
先创建学生对象再让对象打印成绩注:打印成绩可以让对象自行操作面向对象的设计思想是抽象出Class,根据Class创建Instance。
class Student():
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
class Student:
def __init__(aabb, name, score):
aabb.name = name
aabb.score = score
def print_score(aabb):
print('%s: %s' % (aabb.name, aabb.score))
michael = Student('Michael','A')
bob = Student('Bob','C')
michael.print_score()
bob.print_score()
print(michael.name)
print(michael.score)
print(bob.name)
print(bob.score)
实例属性:
一般在构造函数__init__中定义;定义和使用时必须以self作为前缀
属于实例,只能通过对象名访问
类属性:
类中所有方法之前定义的数据成员
通过对象名或类名访问
class Student:
university = "Shenzhen University"
def __init__(self, name, score):
self.name = name
self.score = score
print(bob.name,bob.score,bob.university,Student.university)
print(Student.name)
Student.university = 'SZU’
print(michael.university) #SZU
print(bob.university) #SZU
#增加类属性
Student.major = 'CS’
print(michael.major)
print(bob.major)
michael.score = 'B'
bob.name = 'BOB'
michael.id = 1001
print(michael.id)
print(bob.id)
import types
michael.change_score = types.MethodType(change_score,michael)
michael.change_score('B')
print(michael.score)
bob.change_score('D')
print(bob.score)
del michael.change_score
私有变量
可以把属性的名称前加上两个下划线__
实例的变量名如果以__开头,代表一个私有变量(private)
只有内部可以访问,外部不能访问!
一般通过调用对象的公有成员方法来访问
class Student:
def __init__(self, name, score):
self.__name = name
self.__score = score
def show_score(self):
return self.__score
def change_score(self,score):
self.__score = score
michael = Student('Michael','A')
bob = Student('Bob','C')
print(michael.__score)
print(bob.__name)
print(michael.show_score())
michael.change_score('B')
print(michael.show_score())
michael=Student('Michael','A')
michael.__score ='B'
print(michael.__score)
print(michael.show_score())
print(michael.__name)
print(michael.__score)
print(michael._Student__name)
print(michael._Student__score)
xxx:系统定义的特殊成员、特殊变量、可以直接访问的
__xxx:私有成员,只有类对象自己能访问,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问
_xxx:受保护成员,不能用'from module import *'导入
class Dog:
motion = [] #属于可变类型的列表
def __init__(self, name):
self.name = name
def add_motion(self, motion):
self.motion.append(motion)
d1 = Dog('Fido')
d2 = Dog('Buddy')
d1.add_motion('run')
d2.add_motion('sit')
print(d1.motion) # ['run', 'sit'],这里就是没有将motion进行分类,从而导致了d1和d2动作都放在了一起。
#正确的做法:
class Dog:
def __init__(self, name):
self.name = name
self.motion = []
def add_motion(self, motion):
self.motion.append(motion)
d1 = Dog('Fido')
d2 = Dog('Buddy')
d1.add_motion('run')
d2.add_motion('sit')
print(d1.motion)#['run']
class Student:
def __init__(self, name, score):
self.__name = name
self.__score = score
def show_score(self):
return self.__score
def change_score(self,score):
self.__score = score
michael = Student('Michael','A')
michael.__change_score('B')
michael._Student__change_score('B')
print(michael.show_score())
#例二:宠物
class Pet:
def __init__(self, name, age=0):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def get_age(self):
return self.__age
#内置函数__str__定义当我们打印Pet实例时要发生的操作。在这里我们重写它来打印宠物的名字。
def __str__(self):
return "This pet’s name is " + str(self.__name)
mypet1 = Pet('Ben')
print(mypet1)#This pet’s name is Ben
print(mypet1.get_name()) #Ben
print(mypet1.get_age()) #0
mypet2 = Pet(age=2,name='Bob')
print(mypet2.get_name()) #Bob
print(mypet2.get_age()) #2
类的构造函数(constructor) 是__init__(),一般用来为数据成员设置 初值或进行其他必要的初始化工作,在创建对象时被自动调用和执行。
类的析构函数(destructor) 是__del__(),一般用来释放对象占用的资 源,在Python删除对象和收回对象空间时被自动调用和执行。
#问题:一个列表中每个元素都加上一个相同数字?
#面向过程:
lst = [1,2,3,5]
[(item + 2) for item in lst]
#面向对象:重新编写类 + 重写特殊方法来实现运算符重载(override)
class mylist:
def __init__(self,lst=[]):
self.__size = len(lst)
self.__list = lst
def add_item(self,item):
self.__list.append(item)
#未将面向对象进行到底的写法:
def __add__(self, n): #重写内置函数__add__ 实现运算符重载
temp = mylist()
for item in self.__list:
temp.add_item(item+n)
return temp. __list #这个. __list不纯粹
#如果这里将.__list去除,则print(lst+2)无法正确显示,会报错:<__main__.mylist object at 0x7fad30106160>
lst = mylist([1,2,3,5])
print(lst+2) #[3,4,5,7]
#完全体现面向对象思维的写法:
class mylist:
def __init__(self,lst=[]):
self.__size = len(lst)
self.__list = lst
def add_item(self,item):
self.__list.append(item)
def __add__(self, n):
temp = mylist()
for item in self.__list:
temp.add_item(item+n)
return temp
def __str__(self):
return str(self.__list)
lst = mylist([1,2,3,5])
print(lst+2) #[3,4,5,7],这里返回的是整个对象
#结论:要体现最终的结果,最好使用def __str__(self):这个函数
#例二:点类
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __str__(self):
return "Point({0}, {1})".format(self.x, self.y)
A = Point(3, 4)
B = Point(-1, 2)
str(A) # => Point(3, 4)
print(A + B) # => Point(2, 6)
继承是为代码复用和设计复用而设计的,是面向对象程序设计的重要特性之一。设计一个新类时,如果可以继承一个已有的设计良好的类然后进行二次开发,无疑会大幅度减少开发工作量
#继承——子类与父类
class Animal(object):#父类
def run(self):
print('Animal is running...')
class Dog(Animal):#子类
pass
class Cat(Animal):#子类
pass
#子类获得了父类的全部功能。由于Animial实现了run()方法
#因此,Dog和Cat作为它的子类,自动拥有了run()方法:
dog = Dog()
dog.run() #Animal is running...
cat = Cat()
cat.run() #Animal is running...
#但是这里我们也会发现Dog和Cat都输出Animal,显然是不那么合理的
#多态(Polymorphism)的应用:按字面的意思就是“多种状态”
class Dog(Animal):
def run(self):
print('Dog is running...')
class Cat(Animal):
def run(self):
print('Cat is running...')
dog = Dog()
dog.run() #Dog is running...
#当子类和父类都存在相同的run()方法时,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。
cat = Cat()
cat.run() #Cat is running...
#多态的应用:对子类增加父类没有的方法
class Dog(Animal):
def run(self):
print('Dog is running...')
def eat(self):
print('Dogs like meat...')
class Cat(Animal):
def run(self):
print('Cat is running...')
def eat(self):
print('Cats like fish...')
dog = Dog()
dog.eat() #Dogs like meat...
cat = Cat()
cat.eat() #Cats like fish...
#子类判断函数issubclass(class, classinfo)
class Animal(object):#父类
pass
class Dog(Animal):#子类
pass
class Cat(Animal):#子类
pass
issubclass(Animal, Animal) #T
issubclass(Dog, Animal) #T
issubclass(Cat, Animal) #T
issubclass(Animal, object) #T
issubclass(Dog, object) #T
issubclass(int, Animal) #F
issubclass(list, Animal) #F
class Father:
def __init__(self, iterable=[1,2,3]):
self.items_list = []
self.update(iterable)
def update(self, iterable):
for item in iterable:
self.items_list.append(item)
class Son(Father):
def update(self, keys, values):
for item in zip(keys, values):
self.items_list.append(item)
a=Father()
b=Son()
class Father:
def __init__(self, iterable=[1,2,3]):
self.items_list = []
self.update_father(iterable)
def update_father(self, iterable):
for item in iterable:
self.items_list.append(item)
class Son(Father):
def update_son(self, keys, values):
for item in zip(keys, values):
self.items_list.append(item)
a=Father()
b=Son()
class A(object):
def __init__(self):
self.__private()
self.public()
def __private(self):
print('__private() method in A')
def public(self):
print('public() method in A')
class B(A):
def __private(self):
print('__private() method in B')
def public(self):
print('public() method in B')
b=B()
多态的好处:不用一次性建很多新的类,只需要建立一个公用的类,然后不断进行实体化即可。
#练习
class Animal(object):
def show(self):
print('I am an animal.')
class Cat(Animal):
def show(self):
print('I am a cat.')
class Dog(Animal):
def show(self):
print('I am a dog.')
class Tiger(Animal):
def show(self):
print('I am a tiger.')
class Test(Animal):
pass
x = [item() for item in(Animal, Cat, Dog, Tiger, Test)]
for item in x:
item.show()
输出:
I am an animal.
I am a cat.
I am a dog.
I am a tiger.
I am an animal.
class Canadian:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def print_name(self):
print("I'm {} {}, Canadian!".format(self.first_name,self.last_name))
class American:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def print_name(self):
print("I'm {} {}, American!".format(self.first_name, self.last_name))
class BritishColumbian(Canadian, American):
pass
michael = BritishColumbian("Michael", "Cooper")
michael.print_name()#I'm Michael Cooper, Canadian!
相关知识
Python面向对象高级编程——多重继承
Python———面向对象编程
python之面向对象
pyhton面向对象的实例
案例驱动式Python学习笔记【第六篇】电子宠物
使用面向对象思想设计电子宠物系统
JAVA面向对象编程——学生喂养三种宠物:猫、狗和鸟
【面向对象学习笔记day03】面向对象基础语法+内置函数+定义简单的类+创建对象+第一个面向对象程序+使用 Cat 类再创建一个对象+方法中的self参数+初始化方法+内置方法和属性+del+str
Java面向对象
初识面向对象(猫咪项目)
网址: Python基本思想——面向对象编程 https://m.mcbbbk.com/newsview436025.html
上一篇: 区块链技术应用数字宠物Block |
下一篇: wow猎人宠物特殊 |