面向对象化(封装,继承,多态)

29 篇文章 0 订阅

面向过程,
面向函数,reduce(add,[1,2,3])
面向对象
面向对象的三大特性: 封装, 继承, 多态
先看这个例子

##定义类的过程
class Animal: 
   ##__init__构造函数,当实例化时会自动取调用
   ##self实质上是实例化的对象本身 
    def __init__(self,name,age,weight):
        ##类的属性
        self.name=name
        self.age=age
        self.weight=weight
   # 析构函数; 一般用作类的清理工作,自动调用;
   def __del__(self):
       print "delete........"   
##实例化对象的过程 cat使实例化的一个对象,实例化的属性name,age,weight
cat=Animal('fentiao',10,13)
print cat.name
print cat.age
print cat
---->>结果
fentiao
10
13
<__main__.Animal instance at 0x7fb31c2033f8>
delete........

定义一个类

经典类的格式python2.x
class 类名:
      def __init__(self):self后可以跟类的属性
变量名=类名(添加类的属性)
类名后面有括号的类,称为新式类;python2.xpython3.x
括号里面的内容是父类的名称;程序中,所有类的父类都是 object;
class Animals(object):
    pass
print Animals
<class '__main__.Animals'>

方法的调用,一般方法函数名建议使用动词
类的方法 ==== 函数在类中定义的函数叫做方法 ;
类的方法中, python 解释器要求第一个形参必须是 self

import random
import time
class Animal:
    def __init__(self,name,age,weight):
        self.name=name
        self.age=age
        self.weight=weight
    def eat(self):
        print 'eating...'
        time.sleep(random.random())
        self.weight+=1
        print "%s now weight:%s" %(self.name,self.weight)

    def play(self):
        print 'playing...'
        time.sleep(random.random())
        self.weight-=1
        print "%s now weight:%s" % (self.name, self.weight)

    def __del__(self):
        print '清理中...'
cat = Animal('fentiao',10,12)
print cat.name , cat.age,cat.weight
cat.eat()
cat.play()
del cat
---->>结果
fentiao 10 12
eating...
fentiao now weight:13
playing...
fentiao now weight:12
清理中...

封装,封装实际上是把数据封装到某个地方, 以后再去调用被封装在某处的内容或者数据;

封装数据
调用封装数据
通过对象直接调用;
通过self间接调用
这里写图片描述

class People():
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
    def goHome(self):
        print '%s,%s岁,%s,辍学回家' %(
            self.name,self.age,self.gender)
    def kanChai(self):
        print '%s,%s岁,%s,上山去砍柴' % (
            self.name, self.age, self.gender)
    def quXiFu(self):
        print '%s,%s岁,%s,开车娶媳妇' % (
            self.name, self.age, self.gender)

laoli =People('老李',18,'男')
laoli.quXiFu()
xiao=People('校思浩',22,'男')
xiao.kanChai()
tang=People('唐浩',10,'女')
tang.goHome()

继承

-父类和子类; 基类和派生类;
-注意: 类的属性名和方法名不同相同;
-建议:
-属性名用名词;eg:name, age, weight;
-方法名建议用动词; eg: eat, drink, get_weight;
这里写图片描述
第一种情况,子类不存在__init__函数

class Animal(object):
    def __init__(self,name,age,weight):
        self.name=name
        self.age=age
        self.weight=weight
    def eat(self):
        print 'eating...'

    def play(self):
        print 'playing...'

##Cat: 子类,/派生类; Animal:父类/基类;
# 子类不存在__init__函数, 调用父类的;
# 子类存在__init__函数, 调用子类的;
class Cat(Animal):
    pass

jumao = Cat('jumao',12,14)
print jumao
jumao.play()
---->>
<__main__.Cat object at 0x7f387cb14f50>
playing...

第二种情况:存在__init__函数,执行报错,子类Cat存在__ini__函数,而且参数有两个self和country,很明显子类没有调用Animal父类,
这里写图片描述
如果子类存在构造函数有想调用父类构造函数怎么办?第一种继承方法:可维护性低
-Animal.init(self,name,age,weight)


class Animal(object):
    def __init__(self,name,age,weight):
        self.name=name
        self.age=age
        self.weight=weight
    def eat(self):
        print 'eating...'

    def play(self):
        print 'playing...'
class Cat(Animal):
    def __init__(self,name,age,weight,country):
        Animal.__init__(self,name,age,weight)
        self.name = name
        self.age = age
        self.weight = weight
        self.country=country

jumao = Cat('jumao',12,14,'CHINA')
print jumao.name,jumao.age,jumao.country
jumao.play()
---->>
jumao 12 CHINA
playing...

第二种继承方法:可维护性高

class Animal(object):
    def __init__(self,name,age,weight):
        self.name=name
        self.age=age
        self.weight=weight
    def eat(self):
        print 'eating...'

    def play(self):
        print 'playing...'
class Cat(Animal):
    def __init__(self,name,age,weight,country):
        super(Cat,self).__init__(name,age,weight)
        self.country=country

jumao = Cat('jumao',12,14,'CHINA')
print jumao.name,jumao.age,jumao.country
jumao.play()
--->>
jumao 12 CHINA
playing...

多继承

新式类多继承时, 继承算法是广度优先; 查看方式A.mro()
A - (B,C) -D

经典类多继承时, 继承算法是深度优先;

新式类
class D(object):
    def test(self):
        print "D test"

class C(D):
    def test(self):
        print "C test"

class B(D):
    pass
    # def test(self):
    #     print "B test"

class A(B,C):
    pass
    # def test(self):
    #     print "A test"

a=A()
a.test()
print A.mro()
--->>结果:A首先继承B的属性,但是B此时为空,没有构造函数,与时去继承C,最后执行C的__init__函数,A.mro()是继承的一个顺序
C test
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <type 'object'>]
经典类:没有*.mro()属性
class D():
    def test(self):
        print "D test"

class C(D):
    def test(self):
        print "C test"

class B(D):
    pass
    # def test(self):
    #     print "B test"

class A(B,C):
    pass
    # def test(self):
    #     print "A test"


a=A()
a.test()
--->>结果,A没有构造函数,所以第一时间会去继承B的构造函数,B为空,接着深度挖掘去继承B的父类D的属性,
D test

多态:当父类和子类有相同的方法时, 调用优先执行子类的方法;

实验说明1:子类和父类doc方法共存,调用子类doc方法
class Student(object):
    def __init__(self,name='xiaoming',score=300):
        self.name=name
        self.__score = score

    def doc(self):
        print '这时父类doc方法'

class MathStudnet(Student):
    pass
    def doc(self):
        print '这时子类doc方法'
a=MathStudnet('xiaoli',50)
print a.name
a.doc()
---->>结果
xiaoli
这时子类doc方法
实验说明2:子类无doc方法共存,调用父类doc方法
class Student(object):
    def __init__(self,name='xiaoming',score=300):
        self.name=name
        self.__score = score

    def doc(self):
        print '这时父类doc方法'

class MathStudnet(Student):
    pass

a=MathStudnet('xiaoli',50)
print a.name
a.doc()
---->>结果:
xiaoli
这时父类doc方法
类属性(一)
class Animal(object):
    """Animal class"""
    pass

print Animal.mro()
print Animal.__name__
print Animal.__bases__
print Animal.__doc__,'\n'
print "*"*20+"分割线"+"*"*20,'\n'

cat = Animal()

print cat.__class__
print cat.__module__

---->>结果:
[<class '__main__.Animal'>, <type 'object'>]
Animal
(<type 'object'>,)
Animal class 

********************分割线******************** 

<class '__main__.Animal'>
__main__
关于module

在Package/package01/module01中定义Animal新式类
这里写图片描述

在modelu02中导入该模块,查看cat类模块名
这里写图片描述

两个特别的函数(魔术函数):__repr__(self):和__str__(self):

__repr__(self):调试时自动调用,__str__(self):打印对象时自动调用

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

    def __repr__(self):
        """
        调试时自动调用, a = Animal("xxx")   a
        :return:
        """
        return "Animals:%s" %(self.name)

    def __str__(self):
        """打印对象时,自动调用"""
        return  "%s" %(self.name)

 a = Animal('fentiao')
 print a

实验:

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

    def __repr__(self):
        return '据说调试时自动调用它__repr__(self)'

    def __str__(self):
        return '据说打印时自动调用它__str__(self):'

dog = Animal('habagou')
print dog
---->>结果
据说打印时自动调用它__str__(self):
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值