python基础--继承,类属性,类方法

本文介绍了Python面向对象的三大特性之一——继承,包括单继承、新式类与旧式类的区别,以及super()的使用。同时讲解了私有属性和私有方法的应用场景及其定义。接着,通过实例展示了类属性和类方法的概念,强调类作为一个特殊对象,可以拥有自己的属性和方法。最后,讨论了类方法的定义和使用,指出类方法的第一个参数是cls,可以通过cls访问类的属性和调用其他类方法。

面向对象三大特性之一----继承

单继承:
子类拥有父类的所有方法和属性(子类只需封装自己特有的方法)
“”"

class Animal:
    def eat(self):
        print('吃')
    def drink(self):
        print('喝')
    def run(self):
        print('跑')
    def sleep(self):
        print('睡')

class Cat(Animal):
    def call(self):
        print('喵喵~')

class Hellokitty(Cat):
    def speak(self):
        print('我可以说日语~')

#创建猫对象
#fentiao = Cat()
#fentiao.eat()
#fentiao.drink()
#fentiao.run()
#fentiao.sleep()
#fentiao.call()

hk = Hellokitty()
hk.speak()
子类可以继承父类的所有属性和方法
hk.call()

继承的传递性,子类拥有父类的父类的属性和方法
hk.eat()
hk.drink()
hk.run()
hk.sleep()

Cat类是Animal类的子类,Animal类是Cat类的父类,Cat从Animal类继承
Cat类是Animal类的派生类,Animal类是Cat类的基类,Cat类从Animal类派生

当父类的方法不能满足子类的需求的时候,可以对父类的方法进行重写
1.覆盖父类方法
2.对父类方法进行扩展

"""
 class Animal:
     def eat(self):
         print('吃')
     def drink(self):
         print('喝')
     def run(self):
         print('跑')
     def sleep(self):
         print('睡')

 class Cat(Animal):
     def call(self):
         print('喵喵~')

 class Hellokitty(Cat):
     def speak(self):
         print('我可以说日语~')
     def call(self):
         # 调用原本在父类中封装的方法
         #Cat.call(self)
         super().call() # 只在python3中支持
         print('#@!#@!#@!')

 hk = Hellokitty()
 hk.speak()
 hk.call()

"""
多继承
子类拥有一个父类叫做单继承
子类可以拥有多个父类,并且具有所有父类的属性和方法
例如:孩子会继承自己父亲和母亲的特性
"""

 class A:
     def test(self):
         print('test 方法')
 class B:
     def demo(self):
         print('demo 方法')
 class D:
     def haha(self):
         print('!!!!!!!!!!!!')
 class C(A,B,D):
     """多继承可以让子类对象,同时具有多个父类的属性和方法"""
     pass
#
 c = C()
 c.test()
 c.demo()
 c.haha()


"""
多继承的注意事项:
问题的提出:
如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢?
提示:开发时,应尽量避免这种容易产生混淆的情况
如果父类之间存在同名的属性或方法,因该尽量避免使用多继承
"""
class A:
    def test(self):
        print('A----test 方法')
    def demo(self):
        print('A----demo 方法')

class B:
    def test(self):
        print('B----test 方法')
    def demo(self):
        print('B----demo 方法')


class C(B,A):
    pass

c = C()
c.test()
c.demo()

"""
新式类和旧式(经典)类:
object是Python为所有对象提供的基类,提供有一些内置的属性和方法,可以使用dir函数查看
新式类:以object为基类的类,推荐使用
经典类:不以object为基类的类,不推荐使用
在python3.X中定义的类时,如果没有指定父类,会默认使用object作为基类--python3.x中定义的类都是新式类
在python2.x中定义类时,如果没有指定父类,则不会以object作为基类
####推荐使用新式类#############

新式类和旧式类在多继承时---会影响到方法的搜索顺序

为保证编写的代码能够同时在python2.x和python3.x运行
今后在定义类时,如果没有父类,建议统一继承自object

super

class Parent(object):
    def __init__(self,name):
        print('parent的init开始被调用')
        self.name = name
        print('parent的init结束被调用')

class Son1(Parent):
    def __init__(self,name,age):
        print('Son1的init开始被调用')
        self.age = age
        Parent.__init__(self,name)
        print('Son1的init结束被调用')

class Son2(Parent):
    def __init__(self,name,gender):
        print('Son2的init开始被调用')
        self.gender = gender
        Parent.__init__(self,name)
        print('Son2的init结束被调用')

class Grandson(Son1,Son2):
    def __init__(self,name,age,gender):
        print('grandson的init开始被调用')
        Son1.__init__(self,name,age)
        Son2.__init__(self,name,gender)
        print('grandson的init结束被调用')


gs = Grandson('grandson',18,'男')
print('姓名:',gs.name)
print('年龄:',gs.age)
print('性别:',gs.gender)

在这里插入图片描述

新式类:调用的顺序为广度优先
旧式类:调用顺顺序为深度优先
super()类:不重复的调用父类,解决了钻石继承(多继承)的难题

class Person(object):
    def __init__(self):
        print('我要好好学习')
    def study(self):
        print('我要好好学习语言')

class Man(Person):
    def __init__(self):
        print('我是男的我要好好学习')
    def study(self):
        print('我要学好数学')
        #super().study()
class Womam(Person):
    def __init__(self):
        print('我是女的我要好好学习')
    def study(self):
        print('我要学好英语')
        super().study()

class Son(Man,Womam):
    def __init__(self):
        print('我是儿子我要好好学习')

    def study(self):
        print('我要学好化学和物理')
        #Womam.study(self)
        #Man.study(self)
        super().study()
print(Son.mro())
son1 = Son()
son1.study()
"""
super实现原理:通过c3算法,生成mro(method resolution order)列表,根据列表中元素顺序查询调用
super()不是指父类 而是指以实例化对象为起点的mro序列中的下一个
  
简洁点的三个原则就是:
子类在父类前,所有类不重复调用,从左到右
"""

class A():
    def go(self):
        print ("go A go!")
    def stop(self):
        print ("stop A stop!")
    def pause(self):
        raise Exception("Not Implemented")
class B(A):
    def go(self):
        super(B, self).go()
        print ("go B go!")
class C(A):
    def go(self):
        super(C, self).go()
        print ("go C go!")
    def stop(self):
        super(C, self).stop()
        print ("stop C stop!")
class D(B,C):
    def go(self):
        super(D, self).go()
        print ("go D go!")
    def stop(self):
        super(D, self).stop()
        print ("stop D stop!")
    def pause(self):
        print ("wait D wait!")
class E(B,C):
    pass

a = A()
b = B()
c = C()
d = D()
e = E()

私有属性和私有方法
应用场景及定义方式
应用场景
在实际开发中,对象的某些属性或方法可能只希望在对象的内部使用,而不希望在外部被访问到
私有属性 就是 对象 不希望公开的 属性
私有方法 就是 方法 不希望公开的 方法
定义方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法

class Women(object):
    def __init__(self,name):
        self.name = name
        self.__age = 18

    def __secret(self):
        print('%s 的年龄是 %d' %(self.name,self.__age))

lily = Women('lily')
#print(lily.age)
lily.__secret()

实例

class Date(object):
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day
    # 实例方法(默认情况下会传递对象给echo方法)
    def echo(self):
        print('%s %s %s' %(self.year,self.month,self.day))

    # 默认传递类本身给这个方法
    @classmethod
    def as_string(cls,s):
        #print(cls)
        month,day,year = s.split('/')
        d = cls(year,month,day) # d = Date(2018,10,10)
        return d

    @staticmethod
    def is_vaild(s):
        # 批量将年月日转换成整型
        # month,day,year = s.split('/')
        # month,day,year = [int(i) for i in s.split('/')]
        month,day,year = map(int,s.split('/'))
        return 0<month<=12 and 0<day<=31 and 1<year< 9999

 d = Date(2018,10,10)
 print(d)
 d.echo()

s = '10/10/2018'
print(Date.as_string(s))
 print(Date.is_vaild(s))

 d = Date(2018,10,10)
 print(d.is_vaild('13/10/2019'))

一切皆对象
类也是一个特殊的对象–>类对象
类属性
类方法
“”"
“”"
需求:定义一个工具类
每件工具都有自己额名字
需要知道使用这个类,创建了多少个工具对象
“”"

class Tool(object):
# 1.使用赋值语句定义类属性,记录所有工具的数量
count = 0

def __init__(self,name):
    self.name = name
    # 让类属性的值 +1
    Tool.count += 1
@classmethod
def show_tool_count(cls):
    # cls.count 在类方法内部,访问当前的类属性
    print('工具对象的数量 %d' %(cls.count))

创建工具对象(对象在创建的时候,会自动调用初始化方法)

#print(Tool.count)
tool1 = Tool('斧头')
#tool2 = Tool('榔头')
tool1.show_tool_count()

输出工具对象的属性
使用 类名.属性名 的方式来获取属性名
#print(Tool.count)

“”"
类是一个特殊的对象
Python中一切皆对象
class AAA: 定义的类属性属于类对象
obj1 =AAA: 属于实例对象
在运行程序时,类 同样会被加载到内存
在python中,类 是一个特殊的对象–类对象
在程序运行时,类对象(模板) 在内存中之有一份,使用一个类(模板)可以创建出很多个对象实例
除了封装 实例 的属性和方法外,类对象还可以有自己的属性和方法
1.类属性
2.类方法
通过 类名. 的方式可以直接访问类的属性或者调用类的方法

类方法需要用修饰器@classmethod来标示,告诉解释器这是一个类方法
类方法的第一个参数应该是cls
由哪一个类调用的方法,方法内的cls就是哪一个类的引用
这个参数和实例方法的第一个参数是self类似(哪一个对象调用的方法,self就是哪一个对象的引用)

通过类名调用类方法,调用方法时,不需要传递cls参数

在方法内部
也可以通过cls.访问类的属性
也可以通过cls.调用其他的类方法

静态方法

class Cat(object):
    @staticmethod
    def call():
        print('喵~')

不需要创建对象,直接就可以使用
Cat.call()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值