(十一)Python:面对对象

类的定义

语法示例:

class ClassName:
    #语句1
    ……
    #语句N

一个简单的实例:

class MyClass:
    #自定义的属性
    first=1
    second=2
    #自定义的方法
    def firstFun(self):
        return "firstFun"

注意:如果在
self是什么东西呢?马上解密

对象

语法示例:

objName = ClassName()

一个简单的实例:

#实例化对象
myObj = MyClass()
#访问类的属性和方法
myObj.first
myObj.second
myObj.firstFun()

魔法方法__init__(self)

学过一些面对对象的语言的同学们都知道可以使用构造函数初始化一些属性,那么在python中怎么初始化一些变量呢?
在Pyhton中使用__init__(self)方法,用它来指明一个对象初始化的行为。(注意:init(…)方法并不是第一个调用的方法,并且它不负责实例化对象,第一个调用的方法是__new__(),同时实例化对象的是它。对象销毁时调用__del__()方法)譬如:

class MyClass:
    def __init__(self):
        self.name="MyClass"#初始化name为"MyClass"

myclass = MyClass()
print(myclass.name)

在类中的方法和其他普通方法所不同的是有一个self参数,英文self意思为“自己,本身”,python中呢?用一段代码解密:

class PrintSelf:
    def printSelf(self):
        print(self)
        print(self.__class__)

p = PrintSelf()
p.printSelf()

输出结果:

<__main__.PrintSelf object at 0x00000243FF63B128>
<class ‘__main__.PrintSelf’>

可以发现self指的是我们实例化出的对象p,self.__class__指的就是PrintSelf这个类。同时我们应该注意的是self这个名字并不是固定的,我们可以设置为任何名字。

在python中类似“__方法名__(…)”这中用双下划线表示的方法称之为内置方法,又因为这些方法总是能实现一些意向不到的效果我们也称之为“魔法方法”。在后续将介绍一些常见的魔法方法。

继承

语法示例:

#父类和子类在同一作用域中
class DerivedClassName(BaseClassName1):
    #语句1
    ……
    #语句N

#如果父类在另外一个模块中
class DerivedClassName(modname.BaseClassName1):
    #语句1
    ……
    #语句N

小括号中的表示要继承的父类,如果有多个父类之间用逗号隔开。我们要注意父类的顺序,如果子类使用一个方法而其本身没有,则从左至右在父类中进行查找,先找到哪个父类有就执行谁的。
测试示例:

class BaseClass1:
    def test(self):
        print("BaseClass1")

class BaseClass2:
    def test(self):
        print("BaseClass2")

class SonClass1(BaseClass1,BaseClass2):
    def __init__(self):
        print("Son1")

class SonClass2(BaseClass2,BaseClass1):
    def __init__(self):
        print("Son1")

son = SonClass1()
son.test()
son2 = SonClass2()
son2.test()

这里写图片描述
如果需要在子类中使用父类的某个属性,使用self.name

方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,这个特性和JAVA等语言类似。
如果子类不重写父类的__init__()方法,那么在实例化子类时会自动调用父类的__init__()方法。
测试示例:

class FatherClass:
    def __init__(self):
        print("Father")

class SonClass(FatherClass):
    def test(self):
        print("Son Test")

s = SonClass()

这里写图片描述
如果重写了__init__ ,并要使用父类的__init__ 方法,可以使用 super 关键字:
语法规则:

super(子类,self).__init__(参数1,参数2,....)
或
父类名称.__init__(self,参数1,参数2...)

测试示例:

class FatherClass:
    def __init__(self):
        print("Father")

class SonClass(FatherClass):
    def __init__(self):
        super(SonClass,self).__init__()
        print("Son")

s = SonClass()

这里写图片描述

属性和方法

为了使对象的属性更加安全在JAVA中我们使用private修饰,使用getter/setter方法获取和修改属性,在Python中没有诸如private这些关键字。
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

类属性和实例属性
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++,java中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。实例属性只对某一对象所有,无法通过了类名访问。
测试示例:

class TestClass:
    name="Python"#公有的类属性

    def __init__(self,age,addr):
        self.age = age#公有的实例属性
        self.__addr = addr#私有的实例属性

    def getName(self):
        return self.name
    def getAddr(self):
        return self.__addr


t1=TestClass(1,"xian")
print(t1.getName())
print(t1.age)
print(t1.getAddr())

t2=TestClass(2,"beijing")
print(t2.getName())
print(t2.getAddr())

print(TestClass.name)#公有的类属性可以直接通过类名访问

类方法
介绍了类属性,那么同样也应该存在类方法了。python中的类方法需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以’cls’作为第一个参数的名字,就最好用’cls’了,像self一样),能够通过实例对象和类对象去访问。

class TestClass:
    @classmethod
    def ClassMethod(cls):
        print("ClassMethod")

t = TestClass()
t.ClassMethod()#通过实例对象调用
TestClass.ClassMethod()#通过类调用

静态方法
需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数。在使用语法上和类方法一样。

class TestClass:
    @staticmethod
    def StaticMethod(c):
        print("StaticMethod")

t = TestClass()
t.StaticMethod()#通过实例对象调用
TestClass.StaticMethod()#通过类调用

静态方法和类方法十分类似,它们的区别如下:

  1. 静态方法无需传入self或cls参数,类成员方法需传入代表本类的cls参数;
  2. 静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量;
  3. 静态方法有点像函数工具库的作用,而类成员方法则更接近类似Java面向对象概念中的静态方法。

测试示例:

class TestClass:
    name="Python"
    def __init__(self):
        self.age=22

    @classmethod
    def ClassMethod(cls):
        #无法访问实例属性,只能访问类属性
        print("ClassMethod")

    @staticmethod
    def StaticMethod():
        #无法访问实例属性,也无法访问类属性
        print("StaticMethod")

t = TestClass()
t.ClassMethod()#通过实例对象调用
TestClass.ClassMethod()#通过类调用

TestClass.StaticMethod()
t.StaticMethod()

运算符重载

Python支持运算符重载,我们可以对类的专有方法进行重载。

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)

    def __add__(self, other):#对加运算实现运算符重载
        return Vector(self.a + other.a, self.b + other.b)
    def __sub__(self, other):#对减运算实现运算符重载
        return Vector(self.a-other.a,self.b-other.b)

v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)

v3 = Vector(5, 10)
v4 = Vector(3, 3)
print(v3 - v4)

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_25343557/article/details/81274842