【Python学习笔记】六、类和对象


面向对象的三大特性:继承、封装、多态。

1.创建类

所创建的类中,每一个方法的self参数是必需的(不一定要叫self,也可以是任何其他名字)。在调用方法时,这个参数的值不需要自己传递,系统会将方法所属的对象传入这个参数。而且在方法内部可以利用这个参数调用对象本身的资源(如属性、方法等)。

class Person: #创建一个Person类
    def setname(self,name): #定义setname方法
        self.name=name
    def getname(self):
        return self.name
    def greet(self):
        print("Hello,I'm {name}".format(name=self.name))
person1=Person() #创建person1对象
person2=Person() #创建person2对象
person1.setname("Bill gates") #调用person1对象的setname方法
person2.name="Bill clinton" #调用person2对象的name属性
print(person2.name) #Output:Bill clinton
#调用person1对象的greet方法的两种方式:
person1.greet() #Output:Hello,I'm Bill gates
Person.greet(person1) #Output:Hello,I'm Bill gates

2.方法和私有化

Python类默认情况下所有的方法都可以被外部访问。不过如Java、C#等语言都提供了private关键字将方法私有化(即只有类的内部方法才能访问私有化的方法)。但python并没有提供类似的关键字将方法私有化,所以我们只能迂回解决。

在Python类的方法名前面加双下划线(__)可以让该方法在外部不可访问。但并非绝对的不可访问,Python编译器并没有将其真正的私有化,而是把会将"__methodName"的方法名改成"_ClassName__methodName"的形式。

class Person:
    def method1(self): #公共方法
        print("method1")
    def __method2(self): #私有方法
        print("method2")

p=Person()
p.method1() #Output:method1
p.__method2() #抛出异常
p._Person__method2() #Output:method2

3.类代码块

class定义的类会立即执行代码块中可以立即执行的语句(如print函数)。
在创建MyClass类实例后,可以动态向MyClass对象添加新变量。

class MyClass:
    print("MyClass") #class块中的语句会立刻执行
    count=0
    def counter(self):
        self.count+=1
#Output:MyClass     
   
m=MyClass() 
m.counter()
print(m.count) #Output:1

m.counter()
print(m.count) #Output:2

m.count="abc" #将count变量改成字符串类型
print(m.count) #Output:abc

m.name="Mike" #向m对象动态添加name变量
print(m.name) #Output:Mike

4.类的继承

类的继承指一个类(子类)从另外一个类(父类)中获得了所有的成员。父类的成员可以在子类中使用,就像子类本身的成员一样。

①检测继承关系:issubclass函数

issubclass函数可以判断类与类之间的关系(该函数接收两个参数,第1个参数是子类,第2个参数是父类,是继承关系返回True,否则返回False)。

②显示已知类的父类:__bases __

②如果想要知道已知类的父类(们),可以直接使用"__ bases __ ",这是类的一个特殊属性。

③检测一个对象是否是某一个类的实例:isinstance函数

isinstance函数可以检测一个对象是否是某一个类的实例(该函数接收两参数,第1个参数是要检测的对象,第2个参数是一个类,如果第1个参数指定的对象是第2个参数指定的类的实例则返回True,否则返回False)。

class ParentClass: #父类
    def method1(self):
        print("method1")
class ChildClass(ParentClass): #子类
    def method2(self):
        print("method2")
        
myclass=ChildClass()
myclass.method1() #Output:method1
myclass.method2() #Output:method2
print(issubclass(ChildClass,ParentClass)) #Output:True
print(ChildClass.__bases__) #Output:(<class '__main__.ParentClass'>,)
print(ParentClass.__bases__) #Output:(<class 'object'>,)
print(isinstance(myclass,ChildClass)) #Output:True

issubclass函数和isinstance函数检测到存在间接的关系也会返回True。

5.多继承

如果多个父类中有相同的成员,例如有两个或以上父类中有同名的方法,那么会按着父类书写的顺序继承,先继承的父类同名方法会覆盖后继承的,即写在前面的父类会覆盖写在后面的父类同名的方法。
Java、C#等语言中,如果方法名相同而参数个数和数据类型不同,也会认为是不同的方法,这叫做方法的重载。不过由于python是动态语言,所以python类中不会根据方法参数个数和数据类型进行重载。

class Parent1: 
    def method1(self):
        print("method1")
class Parent2: 
    def method2(self):
        print("method2")
class Parent3:
    def method2(self):
        print("method3")
class MyClass(Parent1,Parent2,Parent3):
    pass #如果类中没有任何代码要加pas语句

m=MyClass()
m.method2() #Output: method2

6.接口

接口其实就是一个规范,指定了一个类中都有哪些成员。
python中并没有如Java、C#这些语言的接口的语法。如果要使用接口,就直接使用对象好了,保险起见可以在调用对象成员之前可以使用hasattr函数或getattr函数判断成员是否属于对象。

①hasattr函数

hasattr(对象,“name”),如果成员在对象中存在返回True,否则返回False。

②getattr函数

getattr(对象,“name”,默认值),如果成员在对象中不存在返回第3个参数指定的默认值。

③setattr函数

setattr(对象,“name”,"new value),如果对象中有name属性,则更新该属性的值,如果没有name属性,则会添加一个新的name属性。

class MyClass: #父类
    def method1(self):
        print("method1")
    def method2(self):
        print("method2")
    def default(self):
        print("default")
my=MyClass()
if hasattr(my,'method1'):
    my.method1() #Output:method1
else:
    print("method1方法不存在")

method=getattr(my,'method2',my.default)
method() #Output:method2
method=getattr(my,'method3',my.default)
method() #Output:default

def method():
    print("动态添加的method3")
setattr(my,'method3',method)
my.method3() #Output:动态添加的method3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值