面向对象

一.  类属性说明

一:我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值

二:特殊的类属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

面向对象实例(人狗大战):

#人狗大战

class Person:
    def __init__(self,name,age,gongji,xieliang):
        self.name = name
        self.age = age
        self.gongji = gongji
        self.xieliang = xieliang
    def fight(self,dog):
        dog.shengming -= 10
        if dog.shengming <=0:
            print('%s 被%s 干死了!'%(dog.name,self.name))
        else :
            print('%s还剩%s血量'%(dog.name,dog.shengming))

class Dog:
    def __init__(self,name,age,shanghai,shengming):
        self.name = name
        self.age = age
        self.shanghai = shanghai
        self.shengming = shengming
    def fight(self, person):
        person.xieliang -= 10
        if person.shengming <= 0:
            print('%s 被%s 干死了!' % (person.name, self.name))
        else:
            print('%s还剩%s血量' % (person.name, person.xieliang))


Tom = Person('小王',19,10,100)
Taidi = Dog('二哈',3,50,20)

Tom.fight(Taidi)                    #二哈还剩10血量
Tom.fight(Taidi)                     #二哈 被小王 干死了!

面向对象的组合方法

  圆环由两个圆组成,圆环的面积等于外圆的面积减去内圆的面积,周长等于外圆的周长加上内圆的周长

from math import pi
class Circle:
    def __init__(self,r):
        self.r=r
    def area(self):
        return pi*(self.r**2)
    def zhouchang(self):
        return 2*pi*(self.r)
class Ring:
    def __init__(self,outside_circle,inside_circle):
        self.outside_circle=Circle(outside_circle)
        self.inside_circle=Circle(inside_circle)
    def area(self):
        return self.outside_circle.area()-self.inside_circle.area()
    def zhiouchang(self):
        return self.outside_circle.zhouchang()+self.inside_circle.zhouchang()
ring=Ring(10,5)
ret=ring.area()
rep=ring.zhiouchang()
print(ret,rep)

二.继承

  单继承

#B继承A
class A:
    pass
class B(A):
    pass
#print(B.__bases__)查看继承
 
 

继承实例

class Animal:
    def __init__(self, name, aggressivity, life_value):
        self.name = name  # 人和狗都有自己的昵称;
        self.aggressivity = aggressivity  # 人和狗都有自己的攻击力;
        self.life_value = life_value  # 人和狗都有自己的生命值;

    def eat(self):
        print('%s is eating'%self.name)

class Dog(Animal):
    pass

class Person(Animal):
    pass

egg = Person('egon',10,1000)
ha2 = Dog('二愣子',50,1000)
egg.eat()

  派生


class Animal:
    def __init__(self,name,age):
        self.name = name
        self.age = age

class Teacher(Animal):
    def __init__(self,name,age,salary):
        #Animal.__init__(self, name, age)
        super().__init__(name, age)
        self.salary = salary
    def teacher(self):
        print('teach Englisher')
class Student(Animal):
    def __init__(self,name,age,xuefei):
        Animal.__init__(self,name,age)
        self.xuefei = xuefei

a = Teacher('张宇',26,2500)
print(a.name)
print(a.age)
print(a.salary)
a.teacher()
 

  多继承

1.
class A:
    def func(self):
        print('A')
class B(A):
    def func(self):
        print('B')
class C(A):
    def func(self):
        print('C')
class D(B,C):
    def func(self):
        print('D')
d = D()
d.func()           #D


2.

class A:
    def func(self):
        print('A')
class B(A):
    def func(self):
        print('B')
class C(A):
    def func(self):
        print('C')
class D(B,C):
    pass
d = D()
d.func()         #B


3.

class A:
    def func(self):
        print('A')
class B(A):
    pass
class C(A):
    def func(self):
        print('C')
class D(B,C):
    pass
d = D()
d.func()      #C


4.


class A:
    def func(self):
        print('A')
class B(A):
    pass
class C(A):
    pass
class D(B,C):
    pass
d = D()
d.func()     #A

 
class A:
    def func(self):
        print('A')
class B(A):
    def func(self):
        print('B')
class E:
    def func(self):
        print('E')
class C(E):
    def func(self):
        print('C')
class D(B,C):
    def func(self):
        print('D')
d = D()
d.func()


   接口类

    接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

class Weichat:
    def pay(self,money):
        print('微信支付了%s'%money)

class Alipay:
    def pay(self,money):
        print('支付宝支付了%s' %money)

def pay(pay_obj,money):
    pay_obj.pay(money)

a = Weichat()
a.pay(100)

  抽象类

    抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

import abc

class All_file(metaclass=abc.ABCMeta):
    all_type = 'file'
    @abc.abstractmethod
    def read(self):
        pass
    @abc.abstractmethod
    def write(self):
        pass

class Txt(All_file):
    def write(self):
        print('txt write')
    def read(self):
        print('txt read')

class Cd(All_file):
    def write(self):
        print('CD write')

    def read(self):
        print('CD read')

class Process(All_file):
    def write(self):
        print('process write')

    def read(self):
        print('process read')

wenbenwenjian = Txt()
wenbenwenjian.read()
yingpanwenjian = Cd()
yingpanwenjian.write()
jinchengwenjian = Process()
jinchengwenjian.read()
print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

  接口类与抽象类的区别

    在java角度来看:Java本来就支持单继承,所以就有了抽象类,没有多继承,所以为了接口隔离原则设计了接口这个概念,支持多继承

    在python角度:python既支持单继承又支持多继承,所以对于接口和抽象类没多大区别

  

  多态

    多态指的是一类事物有多种形态

    动物有多种形态:人,狗,猪

import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('say aoao')
#文件有多种形态:文本文件,可执行文件
import abc
class File(metaclass=abc.ABCMeta): #同一类事物:文件
    @abc.abstractmethod
    def click(self):
        pass

class Text(File): #文件的形态之一:文本文件
    def click(self):
        print('open file')

class ExeFile(File): #文件的形态之二:可执行文件
    def click(self):
        print('execute file')

   封装

    就是把类里的某些属性或者方法变成私有的,不能在类外面使用的

  实例1.当登陆时我们不希望别人知道我们的密码,就在pwd前面加上双下划线,把它变成私有的

class Login:
    def __init__(self,user,pwd):
        self.user = user
        self.__pwd = pwd
    def passwd(self):
        print('password is %s'%self.__pwd)

ps = Login('lili','0217')
ps.passwd()        #password is 0217

  property属性

    只会在面向对象里面出现(property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值)

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def area(self):
        return pi * self.r ** 2
    @property
    def zhouchang(self):
        return 2 * pi * self.r

c = Circle(2)
print(c.area)             #没有@property应该写成print(c.area()),此时就是area方法看作属性
print(c.zhouchang)

  除此之外还有 setter方法和(deleter方法一般不用)

  当使用property方法后,不能在外不修改属性,所以可以利用setter重命名

class Person:
    def __init__(self,name):
        self.__name = name
    @property
    def name(self):
        return self.__name + 'sb'
    @name.setter
    def name(self,new_name):
        self.__name = new_name
Tom = Person('铁蛋')
print(Tom.name)       #铁蛋sb
Tom.name = '狗蛋'
print(Tom.name)       #狗蛋sb

  商场打折

class Goods:

    def __init__(self):
        # 原价
        self.original_price = 100
        # 折扣
        self.discount = 0.8

    @property
    def price(self):
        # 实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price

    @price.setter
    def price(self, value):
        self.original_price = value

    @price.deleter
    def price(self):
        del self.original_price


obj = Goods()
obj.price         # 获取商品价格
obj.price = 200   # 修改商品原价
print(obj.price)
del obj.price     # 删除商品原价

  classmethod方法(类方法)

class Classmethod_Demo():
    role = 'dog'

    @classmethod
    def func(cls):
        print(cls.role)

Classmethod_Demo.func()
#dog

  staticmethod方法(静态方法)

class Staticmethod_Demo():
    role = 'dog'

    @staticmethod
    def func():
        print("当普通方法用")

Staticmethod_Demo.func()
原文地址:https://www.cnblogs.com/wm0217/p/10891000.html