继承
虽然子类Bosi没有__init__()方法,但是父类有,所以子类在继承父类时,这个方法也被继承了。所以只要创建了Bosi的对象,就默认执行继承过来的__init__()方法。
子类在继承的时候,在定义类的时候,小括号()中为父类的名字,父类的属性、方法都会继承给子类。
当子类和父类拥有同一方法是,调用谁的方法。观察如下代码:
子类和父类同有__init__()方法,在对象调用时,子类的__init__()方法会覆盖父类的__init__()方法。
关于对象调用时的地址和继承调用时的地址,观察如下代码:
可以看出,他们的地址是一样的。
私有的属性和方法都不能被继承,也不能被对象直接调用,可以通过方法访问。一般情况下,私有的属性和方法都是不对外公布的,往往用来做内部的事情,起到安全的作用。
一个子类不仅可以单一继承,也可以多继承。当一个子类有多个父类时,具体的操作代码如下:
从以上的例子可以看出,当存在多个父类时,且这些父类拥有同名的方法,子类会按照继承的顺序去调用方法,而不会发生父类方法的重写。
如果想子类父类都有该方法,如何重写子类覆盖的父类方法,方式有两种。具体代码如下:
使用super().父类方法名()可以实现重写父类方法,但因为是按继承顺序调用的父类方法,所以父类F2()中的test ()方法不会被调用。如何在不修改继承顺序的情况下调用父类F2()中的test ()方法。代码如下:
通过父类名.父类方法名(self)可以实现想要访问的父类方法。
对于属性的赋值,如果在子类中对特殊属性赋值时,将会覆盖父类对于共有属性的定义,所以可以采用以上的方法对属性赋值:
通过以上代码,不仅完成了对Dog()这一类特殊属性的赋值,也完成了父类Animal()的通用属性的赋值。
类属性、实例属性
class Student():
name = 'Tony'
__age = 18
stu1 = Student()
print(stu1.name)输出Tony
print(Student.name)输出Tony
print(stu1.__age)报错,不能在类外通过实例对象访问私有的类属性
print(Student.__age)报错,不能在类外通过类对象访问私有的类属性
class People(object):
#类属性
address = '山东'
def __init__(self):
self.name = 'xiaowang'
self.age = 20
p = People()
p.age =12
print(p.address)
print(p.name)
print(p.age)
print(People.address)
print(People.name)
print(People.age)
输出结果如上所示。如何通过实例对象修改类属性?
如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
类方法
是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
class People(object):
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
p = People()
print(p.getCountry())#可以用过实例对象引用
print(People.getCountry()) #可以通过类对象引用
类方法还可以对类属性进行修改
class People(object):
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
@classmethod
def setCountry(cls,country):
cls.country = country
p = People()
print(p.getCountry()) #可以用过实例对象引用
print(People.getCountry()) #可以通过类对象引用
p.setCountry('japan')
print(p.getCountry())
print(People.getCountry())
静态方法
需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数
class People(object):
country = 'china'
@staticmethod
#静态方法
def getCountry():
return People.country
print(People.getCountry())
从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。
网友评论