Python 语法基础 面向对象

文章目录

    • [一 类](#一 类)
    • [二 封装](#二 封装)
      • [1 公开/私有/隐藏属性](#1 公开/私有/隐藏属性)
        • 1.1公开属性
        • [1.2 私有属性](#1.2 私有属性)
        • [1.3 隐藏属性](#1.3 隐藏属性)
      • [2 公开/私有/隐藏方法](#2 公开/私有/隐藏方法)
    • [三 继承](#三 继承)
      • 1单继承
      • 2多继承
      • [3 重写父类方法](#3 重写父类方法)
      • [4 扩展父类方法](#4 扩展父类方法)
      • [5 新式类](#5 新式类)
    • [四 多态](#四 多态)
    • [五 静态方法和类方法](#五 静态方法和类方法)

一 类

1定义

python 复制代码
class Human:#定义类
    name="名字"
    def eat(self):#self是自动生成的对象引用,名字可以改
        print("我喜欢吃饭")    
print(Human.hight)#读取属性

2实例化

python 复制代码
man=Human()#实例化对象
print(man.name)

3类属性与实例属性

3.1 类属性

1 类属性是声明在类名下的属性,所有对象共享一个类属性

3.2 实例属性

增肌实例属性的方法有两种

1 写在构造方法里

python 复制代码
class A:
    def __init__(self,name,age):
        self.name=name
        self.age=age

2 通过对象直接添加

python 复制代码
a.height = 170

3.3 误区

类属性只能用类名修改值,不能用类的对象赋值

python 复制代码
class A:
    claaAttribute = 1
    @classmethod
    def bark(cls, name):#和c#不同 没有静态参数这一说
        print(f"{name}bark")

A.claaAttribute =2#正确,修改类属性
aobj = A()
aobj.claaAttribute =3#错误,对象只能读类属性不能改,这里实际上是添加了一个名为claaAttribute的实例属性

4 new函数

new函数是基类object提供的方法,他在构造函数前执行,返回值是对象的引用

python 复制代码
class A:
    def __init__(self):
        print("构造方法执行")
    def __new__(cls, *args, **kwargs):#这是重写一个new方法
        print("new方法执行")
        return super().__new__(cls)#因为返回值是对象引用,所以必须加return,否则拿不到引用init不会执行
a =A()

5构造函数

python 复制代码
class Human:
    def __init__(self,name,age,height):#注意每侧都有两个下划线
        self.name = name
        self.age= age
        self.height= height

man1=Human("wuzi",18,180)

6析构函数

python 复制代码
class Human:
    def __def__(self):
        print("析构执行")

man= Human()
del man #删除一个对象

二 封装

1 公开/私有/隐藏属性

1.1公开属性

属性默认是公开的,可以在任何地方被访问

python 复制代码
class Human:
    name ="wuzi"
1.2 私有属性

和c#的私有属性不同,py的私有属性可以被外部使用,子类可以继承,但是被另一个py文件通过 from xx import *导入时无法导入

更接近c#的protect

写法

加一个下划线

python 复制代码
class Human:
    _name ="wuzi"
man = Human()
print(man._age)#调用时要带着下划线
1.3 隐藏属性

更接近c#的私有属性,外部不可访问,子类不可继承,另一个Py文件使用 from xx import * 导入时无法导入

写法

直接在属性名前加两个下划线

隐藏的属性不会被继承

python 复制代码
class Human:
    name ="wuzi"
    __age = 20#无法通过对象或类名访问到

如果非要访问隐藏的属性

方法1 python是通过修改变量名实现的隐藏,会被替换为_类名__变量名,直接找这个变量名即可

python 复制代码
class Human:
    name ="wuzi"
    __age = 20
man = Human()
print(man._Human__age) 

方法2 封装一个函数

python 复制代码
class Human:
    name ="wuzi"
    __age = 20
    def GetAge(self):
        return self.__age

man = Human()
print(man.GetAge())

2 公开/私有/隐藏方法

同属性

三 继承

1单继承

python 复制代码
class Human:
    def eat(self):
        print("eat")
    def drink(self):
        print("drink")

#单继承
class Girl(Human):#用()指出父类
    pass

girl = Girl()
girl.eat()

2多继承

python 复制代码
class A:
    pass
class B():
    pass
class C(A,B):
    pass

如果多个父类里有重复的方法,会优先使用靠前的方法,此处用A类的方法(就近原则)

3 重写父类方法

py不需要标记虚方法,直接重写即可

python 复制代码
class Father:
    def money(self):
        print("我有1块钱")

class Son(Father):
    def money(self):
        print("我有2块钱")
son = Son()
son.money()#我有2块钱

4 扩展父类方法

python 复制代码
class Father:
    def money(self):
        print("父类有1块钱")

class Son(Father):
    def money(self):
        #这是三种不同的调用父类方法的写法
        Father.money(self)#方法1
        super().money()#方法2 super()实际上创建了父类的对象  推荐用这种
        super(Son, self).money()#方法3 是方法2的完整写法
        print("子类有2块钱")
son = Son()
son.money()#父类有1块钱 父类有1块钱 父类有1块钱 子类有2块钱

5 新式类

py3的所有类都是新式类,用户自己写的类一定会继承object

之所以叫新式类是因为py2里不显式继承object的话会什么都不继承

以下三种写法是一模一样的

python 复制代码
class A:
    pass
class B():
    pass
class C(object):
    pass

四 多态

和C#一样,只不过由于没有类型,不需要考虑声明父类实例化子类的问题,因为只能实例化子类

python 复制代码
class A:
    def bark(self):
        print('bark')
class B(A):
    def bark(self):
        print('A_bark')
class C(A):
    def bark(self):
        print('B_bark')

def Test(object):
    object.bark()#这里是硬写的,没有任何提示

b= B()
c= C()
Test(b)#A_bark
Test(c)#B_bark

五 静态方法和类方法

静态方法

1定义

使用@staticmethod装饰器装饰的方法就是静态方法

python 复制代码
class A:
    @staticmethod
    def bark():
        print('bark')
2特点

·没有self,cls参数限制

·静态方法调用不需要声明对象,直接用类名就可以

3调用

可以用类名直接调用,也可以用对象调用

python 复制代码
class A:
    @staticmethod
    def bark(name):#和c#不同 没有静态参数这一说
        print(f"{name}bark")
#类名调用
A.bark("Bob")#Bobbark
#对象调用
aobj = A()
aobj.bark("Charlie")#Charliebark

类方法

1定义

类方法是使用@classmethod修饰的方法

python 复制代码
class A:
    @classmethod
    def bark(cls):#cls 是类,可以用它调类属性
        pass
    def Funa(self):#实例方法,无法直接通过类名调用
        pass
2 特点

·可以直接用类名调用

· 可以使用类属性,也可以使用对象调用

python 复制代码
class A:
    claaAttribute = 1
    @classmethod
    def bark(cls, name):#cls 是类,可以用它调类属性
        print(f"{name}bark{cls.claaAttribute}")
        
A.claaAttribute = 2
A.bark("Bob")#Bobbark2

实例方法 静态方法 类方法 的对比

实例方法:对象调用,可以访问实例属性,可以通过类名访问类属性

静态方法:类名或对象调用,可以通过类名访问,无法访问实例属性

类方法:类名或对象调用,可以通过类名访问,无法访问实例属性

python 复制代码
class A:
    claaAttribute = 1
    def __init__(self, b):
        self.b = b
    @classmethod
    def bark(cls, name):#cls 可以访问类属性 由于没有对象,不能访问实例属性
        print(cls.claaAttribute)
        print(A.claaAttribute)

    @staticmethod
    def FunStatic():#静态方法,可以访问类属性 由于没有对象,不能访问实例属性
        print(A.claaAttribute)

    def Funa(self):#实例方法,无法直接通过类名调用
        print(A.claaAttribute)
        print(self.b)

类方法和静态方法主要优势在于继承,类方法里的cls会自动变成子类的(子类赋值同名类属性不会影响父类),而静态方法只能静态写死