Python既是面向过程也是面向对象的
C是完全面向过程的
JAVA是完全面向对象的
1、创建类,在init方法中添加属性,self和默认值,创建对象,访问属性,修改属性
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
print(d1.name, d1.height, d1.blood, d1.power)
d1.blood = 9
d1.power = 5
print(d1.name, d1.height, d1.blood, d1.power)
输出:
大黄 0.7 10 3
大黄 0.7 9 5
2、添加方法,调用方法
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{},身高{},血量{},攻击力{}".format(self.name, self.height, self.blood, self.power))
def attack(self, dog2):
dog2.blood = dog2.blood - self.power
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
d1.bark()
d2.bark()
d1.attack(d2)
d2.bark()
输出:
我是大黄,身高0.7,血量10,攻击力3
我是二黑,身高0.5,血量10,攻击力4
我是二黑,身高0.5,血量7,攻击力4
3、通过方法改变属性的值
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{},身高{},血量{},攻击力{}".format(self.name, self.height, self.blood, self.power))
def attack(self, dog2):
dog2.reduce_blood(self.power)
def reduce_blood(self, reduce_value):
if reduce_value > self.blood:
self.blood = 0
else:
self.blood = self.blood - reduce_value
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
d1.bark()
d2.bark()
d1.attack(d2)
d2.bark()
4、类属性,通过类修改类属性,通过对象修改类属性
类属性:
- 整个类只有一份,所有的对象都共享这一份
- 可以通过类或对象访问类属性,访问的都是同一个
- 修改类属性需要通过类
- 因为通过对象会给该对象自己创建一个同名属性
- 对象属性和类属性同名时,使用对象访问优先使用对象属性
class Dog:
num_of_dogs = 0 # 类属性
def __init__(self, name, height, power): # 实例属性
self.name = name
self.height = height
self.power = power
self.blood = 10
print("{}出生了,汪汪".format(self.name))
def bark(self):
print("我是{},身高{},血量{},攻击力{}".format(self.name, self.height, self.blood, self.power))
def attack(self, dog2):
dog2.reduce_blood(self.power)
def reduce_blood(self, reduce_value):
if reduce_value > self.blood:
self.blood = 0
else:
self.blood = self.blood - reduce_value
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
print(Dog.num_of_dogs) # 通过类访问类属性
print(d2.num_of_dogs) # 通过对象访问类属性
Dog.num_of_dogs = 8 # 通过类修改类属性
print(Dog.num_of_dogs)
print(d2.num_of_dogs)
输出:
大黄出生了,汪汪
二黑出生了,汪汪
0
0
class Dog:
num_of_dogs = 0 # 类属性
def __init__(self, name, height, power): # 实例属性
self.name = name
self.height = height
self.power = power
self.blood = 10
print("{}出生了,汪汪".format(self.name))
def bark(self):
print("我是{},身高{},血量{},攻击力{}".format(self.name, self.height, self.blood, self.power))
def attack(self, dog2):
dog2.reduce_blood(self.power)
def reduce_blood(self, reduce_value):
if reduce_value > self.blood:
self.blood = 0
else:
self.blood = self.blood - reduce_value
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
# print(Dog.num_of_dogs) # 通过类访问类属性
# print(d2.num_of_dogs) # 通过对象访问类属性
# Dog.num_of_dogs = 8 # 通过类修改类属性
# print(Dog.num_of_dogs)
# print(d2.num_of_dogs)
d1.num_of_dogs = 8 # 通过对象修改类属性
print(Dog.num_of_dogs)
print(d1.num_of_dogs) # 通过对象修改类属性,并不是修改类属性,而是给自己创建了一个同名属性
print(d2.num_of_dogs)
输出:
大黄出生了,汪汪
二黑出生了,汪汪
0
8
0
5、类方法
类方法:
- 类方法可以通过类名调用,也可以通过对象名调用
- 类方法不能访问实例属性、实例方法,但类方法可以访问类属性
- 类方法需要@classmethod, 第一个参数是cls,访问类属性cls.属性名
class Dog:
# num_of_dogs = 0 # 类属性
dogs = []
@classmethod
def num_of_dogs(cls): # 类方法
return len(cls.dogs) # 在类里面访问类属性:cls.属性名
@classmethod
def biggest(cls):
max_height = 0
for d in cls.dogs:
if d.height > max_height: # 在属性方法里访问实例属性:对象名.实例属性名
max_height = d.height
return max_height
def __init__(self, name, height, power): # 实例属性
self.name = name
self.height = height
self.power = power
self.blood = 10
# Dog.num_of_dogs += 1
Dog.dogs.append(self)
print("{}出生了,汪汪".format(self.name))
def bark(self):
print("我是{},身高{},血量{},攻击力{}".format(self.name, self.height, self.blood, self.power))
def attack(self, dog2):
dog2.reduce_blood(self.power)
def reduce_blood(self, reduce_value):
if reduce_value > self.blood:
self.blood = 0
else:
self.blood = self.blood - reduce_value
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
print(Dog.dogs) # 通过类访问类属性
print(d2.dogs) # 通过对象访问类属性
print(Dog.num_of_dogs()) # 通过类调用类方法
print(d1.num_of_dogs()) # 通过对象调用类方法
print(d2.biggest())
输出:
大黄出生了,汪汪
二黑出生了,汪汪
[<__main__.Dog object at 0x00000204828D4508>, <__main__.Dog object at 0x00000204828D45C8>]
[<__main__.Dog object at 0x00000204828D4508>, <__main__.Dog object at 0x00000204828D45C8>]
2
2
0.7
6、静态方法
静态方法:
- 静态方法@staticmethod
- 不需要传入类或实例作为第一个参数
- 静态方法调用方式与类方法一样
class Dog:
# num_of_dogs = 0 # 类属性
dogs = []
@classmethod
def num_of_dogs(cls): # 类方法
return len(cls.dogs) # 在类里面访问类属性:cls.属性名
@classmethod
def biggest(cls):
max_height = 0
for d in cls.dogs:
if d.height > max_height: # 在属性方法里访问实例属性:对象名.实例属性名
max_height = d.height
return max_height
@staticmethod
def intro(): # 静态方法第一个参数,不需要cls或self
print("dog is human's best friend")
def __init__(self, name, height, power): # 实例属性
self.name = name
self.height = height
self.power = power
self.blood = 10
# Dog.num_of_dogs += 1
Dog.dogs.append(self)
print("{}出生了,汪汪".format(self.name))
def bark(self):
print("我是{},身高{},血量{},攻击力{}".format(self.name, self.height, self.blood, self.power))
def attack(self, dog2):
dog2.reduce_blood(self.power)
def reduce_blood(self, reduce_value):
if reduce_value > self.blood:
self.blood = 0
else:
self.blood = self.blood - reduce_value
d1 = Dog("大黄", 0.7, 3)
d2 = Dog("二黑", 0.5, 4)
Dog.intro() # 通过类名调用静态方法
d2.intro() # 通过对象名调用静态方法
输出:
大黄出生了,汪汪
二黑出生了,汪汪
dog is human's best friend
dog is human's best friend
7、继承和super()
继承:
- 父类有什么属性和方法,子类对象都可以调用
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{},身高{}".format(self.name, self.height))
class SheepDog(Dog):
def __init__(self, name, height, power, num_of_sheeps):
super().__init__(name, height, power)
self.num_of_sheeps = num_of_sheeps
sd = SheepDog("牧羊犬1", 0.6, 4, 5)
print(sd.name, sd.blood, sd.num_of_sheeps) # 子类对象访问父类属性、访问子类属性
sd.bark() # 子类对象调用父类方法
输出:
牧羊犬1 10 5
我是牧羊犬1,身高0.6
8、给子类添加方法
- 子类默认继承父类的所有属性和方法
- 同时,子类也可以有自己独特的属性和方法
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{},身高{}".format(self.name, self.height))
class SheepDog(Dog):
def __init__(self, name, height, power, num_of_sheeps):
super().__init__(name, height, power)
self.num_of_sheeps = num_of_sheeps
def protect(self):
print("我开始保护小羊啦!")
class PoliceDog(Dog):
def __init(self, name, height, power, ability):
super().__init__(name, height, power)
self.ability = ability
class PetDog(Dog):
def __init__(self, name, height, power, price):
super().__init__(name, height, power)
self.price = price
sd = SheepDog("牧羊犬1", 0.6, 4, 5)
print(sd.name, sd.blood, sd.num_of_sheeps) # 子类对象访问父类属性、访问子类属性
sd.bark() # 子类对象调用父类方法
sd.protect()
输出:
牧羊犬1 10 5
我是牧羊犬1,身高0.6
我开始保护小羊啦!
9、重写父类方法
- 子类有与父类的同名方法,则默认调用子类的同名方法
- 如果要在子类调用父类同名方法,可以使用super()调用
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{}Dog类的bark方法,身高{}".format(self.name, self.height))
class SheepDog(Dog):
def __init__(self, name, height, power, num_of_sheeps):
super().__init__(name, height, power)
self.num_of_sheeps = num_of_sheeps
def protect(self):
print("我开始保护小羊啦!")
def bark(self):
print("我是牧羊犬子类的bark方法")
class PoliceDog(Dog):
def __init(self, name, height, power, ability):
super().__init__(name, height, power)
self.ability = ability
class PetDog(Dog):
def __init__(self, name, height, power, price):
super().__init__(name, height, power)
self.price = price
sd = SheepDog("牧羊犬1", 0.6, 4, 5)
print(sd.name, sd.blood, sd.num_of_sheeps) # 子类对象访问父类属性、访问子类属性
sd.bark() # 子类对象调用父类方法
sd.protect()
输出:
牧羊犬1 10 5
我是牧羊犬子类的bark方法
我开始保护小羊啦!
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{}Dog类的bark方法,身高{}".format(self.name, self.height))
class SheepDog(Dog):
def __init__(self, name, height, power, num_of_sheeps):
super().__init__(name, height, power)
self.num_of_sheeps = num_of_sheeps
def protect(self):
print("我开始保护小羊啦!")
def bark(self):
print("我是牧羊犬子类的bark方法")
super().bark()
class PoliceDog(Dog):
def __init(self, name, height, power, ability):
super().__init__(name, height, power)
self.ability = ability
class PetDog(Dog):
def __init__(self, name, height, power, price):
super().__init__(name, height, power)
self.price = price
sd = SheepDog("牧羊犬1", 0.6, 4, 5)
print(sd.name, sd.blood, sd.num_of_sheeps) # 子类对象访问父类属性、访问子类属性
sd.bark() # 子类对象调用父类方法
sd.protect()
输出:
牧羊犬1 10 5
我是牧羊犬子类的bark方法
我是牧羊犬1Dog类的bark方法,身高0.6
我开始保护小羊啦!
10、命名规则
11、模块、类和引入
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{}Dog类的bark方法,身高{}".format(self.name, self.height))
class SheepDog(Dog):
def __init__(self, name, height, power, num_of_sheeps):
super().__init__(name, height, power)
self.num_of_sheeps = num_of_sheeps
def protect(self):
print("我开始保护小羊啦!")
def bark(self):
print("我是牧羊犬子类的bark方法")
super().bark()
class PoliceDog(Dog):
def __init(self, name, height, power, ability):
super().__init__(name, height, power)
self.ability = ability
class PetDog(Dog):
def __init__(self, name, height, power, price):
super().__init__(name, height, power)
self.price = price
if __name__ == "__main__":
sd = SheepDog("牧羊犬1", 0.6, 4, 5)
print(sd.name, sd.blood, sd.num_of_sheeps) # 子类对象访问父类属性、访问子类属性
sd.bark() # 子类对象调用父类方法
sd.protect()
import dog
pd = dog.PetDog("京巴", 0.2, 1, 988)
print(pd.blood)
pd.bark()
12、继承标准库中的类
import turtle as t
class MyTurtle(t.Turtle):
def draw_circle(self):
self.color("red")
self.circle(100)
t = MyTurtle()
t.draw_circle()
13、把对象作为属性
class Dog:
def __init__(self, name, height, power):
self.name = name
self.height = height
self.power = power
self.blood = 10
def bark(self):
print("我是{}Dog类的bark方法,身高{}".format(self.name, self.height))
class SheepDog(Dog):
def __init__(self, name, height, power, num_of_sheeps):
super().__init__(name, height, power)
self.num_of_sheeps = num_of_sheeps
def protect(self):
print("我开始保护小羊啦!")
def bark(self):
print("我是牧羊犬子类的bark方法")
super().bark()
class PoliceDog(Dog):
def __init(self, name, height, power, ability):
super().__init__(name, height, power)
self.ability = ability
class PetDog(Dog):
def __init__(self, name, height, power, price, house):
super().__init__(name, height, power)
self.price = price
self.house = house
class DogHouse():
def __init__(self, no):
self.no = no
print("已创建狗窝{}".format(self.no))
if __name__ == "__main__":
# sd = SheepDog("牧羊犬1", 0.6, 4, 5)
# print(sd.name, sd.blood, sd.num_of_sheeps) # 子类对象访问父类属性、访问子类属性
# sd.bark() # 子类对象调用父类方法
# sd.protect()
house = DogHouse("9527")
pd = PetDog("京巴", 0.2, 1, 988, house)
pd.bark()
输出:
已创建狗窝9527
我是京巴Dog类的bark方法,身高0.2
14、dog版本的吃鸡游戏
import random
class Dog:
dogs = [] # 保存所有活着的dog
def __init__(self, name):
self.name = name
self.attack_power = 5
self.defense_power = 3
self.blood = 100
def attack(self, dog2):
print("{}攻击{},攻击方的攻击力为:{},防御方的防御力为:{}".format(self.name, dog2.name, self.attack_power, dog2.defense_power))
point = self.attack_power - dog2.defense_power
if dog2.blood > point:
dog2.blood -= point
print("{}受到攻击,奋力反击,血量减少为{}".format(dog2.name, dog2.blood))
else:
dog2.blood = 0
print("{}受到攻击,失血过多,死亡".format(dog2.name))
Dog.dogs.remove(dog2) # 在类里面调用类属性,类名.属性名
def dog_type(self):
if isinstance(self, SheepDog):
return "牧羊犬"
elif isinstance(self, PoliceDog):
return "警犬"
else:
return "普通犬"
class SheepDog(Dog):
def __init__(self, name):
super().__init__(name)
self.attack_power = random.randint(5, 10)
self.defense_power = random.randint(3, 5)
print("牧羊犬{}问世".format(self.name)) # 在子类里访问父类属性,self.父类属性名
self.dogs.append(self) # 在子类里修改父类属性,self.父类属性名=值
class PoliceDog(Dog):
def __init__(self, name):
super().__init__(name)
self.attack_power = random.randint(8, 13)
self.defense_power = random.randint(1, 3)
print("警犬{}问世".format(self.name)) # 在子类里访问父类属性,self.父类属性名
self.dogs.append(self) # 在子类里修改父类属性,self.父类属性名=值
# 1.首先创建100个dog:50个SheepDog,50个PoliceDog
# 2.每一轮游戏,随机选出2个dog
# 3.这2个dog互相攻击:dog1先攻击dog2,然后dog2攻击dog1
# 4.任何一方血量变为0即死亡,死亡的dog退出游戏
# 5.最后只剩一个dog,游戏结束,胜利者可以吃鸡
from dog import *
import random
import time
for i in range(100): # 创建100只dog
if i % 2 == 0:
SheepDog(i + 1) # from 模块名 import * 模式下,直接用模块里的功能名
else:
PoliceDog(i + 1)
while True: # 游戏循环
# 首先判断是否只有1个dog
if len(Dog.dogs) == 1: # from 模块名 import * 模式下,直接用模块里的功能名
winner = Dog.dogs[0]
print("🐔🐔🐔🐔🐔🐔🐔🐔🐔🐔")
print("大吉大利,今晚吃鸡!")
print("赢家是:{}{}号".format(winner.dog_type(), winner.name)) # 在类外面调用类方法,对象名.类方法名()。在类外面访问类属性,对象名.类属性名
print("🐔🐔🐔🐔🐔🐔🐔🐔🐔🐔")
break
dog1, dog2 = random.sample(Dog.dogs, 2)
dog1.attack(dog2)
dog2.attack(dog1)
# time.sleep(0.001)
PS:source,maishucode