#定义类和创建类的实例
'''
类似于构造方法,python中有一个类初始化的方法 __init__()
该方法会传递一个参数self,指向实例本身的引用,用于访问类中的属性和方法
__init__()的第一个参数必须是self(可以是其他名字,一般叫self), 一般不需要指定这个self实参
'''
#__self__() 方法名称中,开头和结尾处是两个下划线(中间没有空格),这是一种约定,旨在
#区分python默认方法和普通方法
'''
class Geese:
"大雁类" #类文档字符串
def __init__(self):
print("这是一只大雁")
pass #pass 暂时代替类体
wildGoose = Geese() #创建大雁类的实例
print(wildGoose) #<__main__.Geese object at 0x000001E763627A08>
'''
#创建类成员并访问
'''
1.创建实例方法
第一个参数必须是self,且形参第一个参数必须包含self参数
2.创建数据成员
(类属性)可以在类的所有实例之间共享值,<<< 在所有实例化对象中共用 >>>
可以通过类名或对象名访问。
(实例属性)定义在类的方法中的属性,只作用于当前实例中
只能通过对象名访问
'''
### 通过类名或对象名可以访问属性 ###
### 属性在所有对象中共享 ###
class Geese:
"大雁类"
beak = ''
wing = ''
claw = ''
number = 0
def __init__(self, beak, wing, claw):
print("这是一只大雁,特征如下:")
print(beak)
print(wing)
print(claw)
Geese.beak = beak #类属性 # self.beak = beak 这是实例属性
Geese.wing = wing
Geese.claw = claw
Geese.number += 1
def fly(self, state):
print(state)
beak_1 = "嘴巴基部较高,长度和头部的长度几乎相等"
wing_1 = "翅膀长而坚"
claw_1 = "爪子是蹼状的"
beak_4 = "嘴巴基部较高,长度和头部的长度几乎相等 ..."
wing_4 = "翅膀长而坚 ..."
claw_4 = "爪子是蹼状的 ..."
#wildGoose = Geese(wing = wing_1, claw = claw_1, beak = beak_1)
#print(wildGoose)
list1 = [] #创建空列表
for i in range(4):
beak = beak_1 + " " + str(i)
wing = wing_1 + " " + str(i)
claw = claw_1 + " " + str(i)
list1.append(Geese(beak, wing, claw))
print(list1[i].number) #类属性 在类的所有实例之间共享值
print("一共有" + str(Geese.number) + "只大雁")
print(Geese.beak) #类属性 在类的所有实例之间共享值
print(Geese.wing)
print(Geese.claw)
print()
print(list1[1].beak) #修改类属性,结果应用到该类的所有实例
print(list1[1].wing)
print(list1[1].claw)
#动态为类和对象添加属性
#list1[2].neck = "脖子很长 222"
Geese.neck = "脖子很长 222" #添加类属性,修改类属性,结果将应用于该类的所有实例
print(list1[1].neck)
print(Geese.neck)
#访问限制
'''
1.首尾双下划线表示定义特殊方法,一般是系统定义姓名
2.双下划线 __ 表示private类型的成员,只允许定义该方法的类本身进行访问,不能通过
类的实例进行访问,但是可以通过 <实例名._类名__xxx> 方式访问
单下划线 _ 表示protected类型的成员,和普通属性一样,更多的是一种编码约定
'''
print()
class Swan:
"天鹅类"
__neck_swan = '天鹅脖子很长'
_neck_swan0 = '天鹅脖子很长0'
def __init__(self):
self.__neck_swan1 = '天鹅脖子很长1'
self._neck_swan2 = '天鹅脖子很长2'
print("__init__", Swan.__neck_swan)
swan = Swan()
Swan._Swan__neck_swan = 123
print(swan._Swan__neck_swan)
print(Swan._Swan__neck_swan)
print(swan._neck_swan0)
print(Swan._neck_swan0)
swan._Swan__neck_swan1 = 456
print(swan._Swan__neck_swan1)
#print(Swan._Swan__neck_swan1) #实例属性 不可访问
print(swan._neck_swan2)
#print(Swan._neck_swan2) #实例属性 不可访问
Swan.__neck_swan = "123456"
print(swan._Swan__neck_swan)
print(swan.__neck_swan) #123456
print(Swan.__neck_swan) #123456
print(Swan.__dict__) #获取对象中所有信息描述
print(swan.__dict__) #获取实例中所有信息描述
#属性(property)
'''
不同于类属性和实例属性,是一种特殊的属性
1.创建用于计算的属性
使用 @property(装饰器) 将一个方法转换为属性,这样可以直接通过方法名访问,不用添加()
'''
print()
class Rect:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
rect = Rect(800, 600)
print("面积是", rect.area)
'''
2.创建一个可读不可写的属性,可以用@property修饰实现只读属性
'''
class TVshow:
def __init__(self, show):
self.__show = show
@property
def show(self):
return self.__show
tvshow = TVshow("456")
print(tvshow.show)
tvshow._TVshow__show = "123"
print(tvshow.show)
'''
在程序设计中实现继承,表示这个类拥有它继承的类的所有<公有成员>或<受保护成员>
'''
#方法重写
'''
基类的成员被派生类继承,在派生类中重写父类的这个方法
'''
#在派生类中调用基类的 __init__()方法
'''
在派生类中定义__init__()方法,不会自动调用基类的__init__()方法
'''
class Fruit:
def __init__(self, color = "绿色"):
Fruit.color = color #创建类属性
def harvest(self):
print("水果原来是:" + Fruit.color + "的")
class Apple(Fruit):
def __init__(self):
print("我是苹果")
super().__init__() #调用基类的__init__()方法
apple = Apple()
#apple.harvest() #Fruit类没有color属性
apple.harvest()