【Python】面向对象

编程的两大特点

  1. 面向过程:着重于做什么
  2. 面向对象( oop):着重于谁去做

python是面向对象语言,面向对象三大特点:封装、继承、多态
面向对象:便于代码管理,方便迭代更新。

新式类、经典类

继承了python内置类的称为新式类,否则是经典类
python3类:新式类python3中所有的类默认继承object(基类),所以一般的类都是新式类
python2类:必须显示声明继承内置类才是新式类,否则是经典类
两个类之间的区别:继承顺序的不同

  • 新式类:c3算法
  • 经典类:深度优先算法

python 类可以多重继承也可以继承多个

程序员:看做是造物主
类:具有相同属性和方法的对象的集合
对象(实例) :实实在在的例子,某一个类实例化之后的结构体
属性:对象的描述信息,静态数据
方法:能做什么

创建和实例化一个类

class User():
	# 类属性(公共属性)
    school="sctl"
    money=5000

    #构造方法(个性化属性)
    def __init__(self,name,age,address,password):
    	# 实例属性
        self.name = name
        self.age = age
        self.address = address
        self.password = password
        self.money = 900

# 实例化对象
user1 = User("张三","20","长沙", "123456")
user2 = User("李四","30","武汉", "abcd")

属性的查找

1、先在当前实例空间查找属性和方法,找到即刻返回
2、没找到,通过类对象指针,去类空间查找
3、类空间没有,就去父类查找

user1.name = "wangwu"
print(user1.name)

#将user1实例空间中添加了一个school属性,就不会像user2去类空间中找了
user1.school = "cssc"
print(user1.school,user2.school)

创建实例的流程和三种方法

手动创建实例
1、调用object的new方法,创建一个实例
2、调用init方法初始化一个实例

三种方法:
静态方法、实例方法、类方法

class User():
    school="sctl"
    money=5000

    #构造方法
    def __init__(self,name,age,address,password):
        self.name = name
        self.age = age
        self.address = address
        self.password = password
        self.money = 900

    #实例方法
    def chongzhi(self, amount):
        self.money += amount
        print(f"充值了{amount},余额为{self.money}")

	#类方法
    # classmethod 内置装饰器
    @classmethod
    def chongzhi1(cls, amount):
        cls.money += amount
        print(f"充值了{amount},余额为{cls.money}")

	# 静态方法
    @staticmethod
    def chongzhi2(amount):
        User.money += amount
        print(f"充值了{amount},余额为{User.money}")



user3 = object.__new__(User)
User.__init__(user3, "luobozi",18,"cs","12345")
user3.chongzhi(632)
user3.chongzhi1(500)
user3.chongzhi2(600)

继承

继承的作用:实现代码复用

class Animal:
    def __init__(self):
        self.species="dog"
        self.count=1
    def eat(self):
        print("i can eat")
    def breath(self):
        print("i can breath")


class Cat(Animal):  #继承Animal类
    pass


c1=Cat()
# 记住创建实例的步骤
#1.调用父类(object)的new方法创建实例
#2.再去找init构造函数,但是Cat没有构造函数,所以去找父类的构造函数执行,得到了species的值
#这里不是获取了父类的属性,而是自己没有init,而去寻找了父类,执行了父类的init
print(c1.species)

既然这样那我们在Cat子类中创建构造函数,那么创建实例的时候就不会去找父类的init了
自然我们也就没有了species属性,那么我们想要使用父类的属性怎么办?
可以在子类的init中写super实现继承父类的方法和属性

class Animal:
    def __init__(self):
        self.species="dog"
        self.count=1
    def eat(self):
        print("i can eat")
    def breath(self):
        print("i can breath")


class Cat(Animal):  #继承Animal类
    def __init__(self,name):  #重写init函数
        self.name= name
        super().eat()      #super 是子类去访问父类的方法
        super().__init__()  #继承父类的init中的属性

c1=Cat("小猫")
#创建Cat的init函数后,它将不会去寻找父类的init函数了
print(c1.name)
#但是我们也想继承父类init中的属性,又想有自己的init函数怎么办?
print(c1.species)  # 通过super获取父类的属性

通过继承创建一个属于我们的字典类型

#自定义一个字典,添加一个排序功能
class Mydict(dict):
    def sort(self):
        return dict(sorted(self.items(),key=lambda x:x[1],reverse=True))

d1=Mydict()
d1["x"]=1
d1["y"]=14
d1["z"]=12

print(d1.sort())
print(type(d1))
#isinstance判断d1是否为对应的类型 返回bool类型的值
print(isinstance(d1,Mydict))
print(isinstance(d1,dict))

多态

python原生支持多态,动态类型语言,不需要额外的实现
python崇尚鸭子类型,一直鸟走起来像鸭子,游泳起来像鸭子,那么它就是鸭子
不关心对象的具体类型,只关心有没有对应的行为

class ZFB():
    def Pay(self):
        pass
class WX():
    def Pay(self):
        pass

def payFunc(payobj):
#这就是只关心有没有这个行为,不管它是不是zfb、wx、yhk,只要有这个方法就可以了。
#(其它语言一般需要指定类型,比如在这些子类基础上再创建一个pay的父类,设置类型为pay,实现多态)
    payobj.pay() 

私有属性

python中的私有属性是伪私有,其实就是给私有属性改名了!

class A:
    def __init__(self,name):
        self.name=name
        self.__age=20
    def show(self):
        print("self.__age:",self.__age)  #只有函数内部可以调用


a1=A("luobozi")
print(a1.name)
#print(a1.__age) #报错,因为是私有属性
a1.show()

#python中的私有属性是伪私有,其实就是给私有属性改名了!
print(a1.__dict__)
#{'name': 'luobozi', '_A__age': 20}
print(a1._A__age)

魔术方法

在类中定义,由双下划线开头双下划线结尾,并且不需要显示调用,某种场合自动执行的方法。
魔术方法都是有特殊含义的
__lt__遇到小于号执行的方法
__init__创建完实例后执行的方法
__new__创建实例调用的方法

print(  dir(object)  ) # 查看常见的魔术方法

class A:
    def __init__(self, name , age, count):
        self.name = name
        self.age = age
        self.count = count
    def __lt__(self, other): #遇到 小于号执行的 魔术方法lt,自动将表达式的第二个参数传递到other
        return abs(self.count) < abs(other.count)
a1 = A("zhangsan", 20, 5)
a2 = A("lisi", 18, -8)
if a1 < a2:
    print("a1小于a2")

抽象基类 ABC

定义接口规范,类不能实例化,规定子类必须实现父类的抽象方法,强制规范子类行为的机制

from abc import ABC, abstractmethod

class GameCharacter(ABC):  #继承ABC都是抽象基类
    @abstractmethod
    def attack(self):
        """必须实现的攻击方法"""
        pass
        
    @abstractmethod
    def defend(self):
        """必须实现的防御方法"""
        pass
        
    def blood(self):
        pass
        
class WZJ(GameCharacter):  
    def attack(self):
        print("attack")
    def defend(self):
        print("defend")
        
w1 = WZJ() #如果WZJ不实现attack、defend这两个方法就会报错!

补充知识

先有鸡还是现有蛋啊!!!!
type – 元类 创建类的类
object – 继承 所有类的父类
#obj = type(obj)

class A:
    pass
print( type(A) )

你可能感兴趣的:(Python,python)