面向对象基础

Posted xone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象基础相关的知识,希望对你有一定的参考价值。

1、面向对象不是所有情况都适用

2、面向对象编程

  a.定义类

    class 类名:

      def 方法1(self,bb):

        pass

  b.根据类创建对象

    使用对象去执行类中方法

实例

class Home:
    def __init__(self, new_area, new_type, new_addr):
        self.area = new_area
        self.type = new_type
        self.addr = new_addr
        self.left_area = new_area

    def __str__(self):
        msg = """
        住房面积:%s
        可用面积:%s
        户型:%s
        住房地址:%s
        """%(self.area, self.left_area, self.type, self.addr)
        return msg

    def add_item(self, item):
        self.left_area -= item.get_bed_size()

class Bed:
    def __init__(self, new_bed_size, new_bed_type):
        self.bed_size = new_bed_size
        self.bed_type = new_bed_type
    def __str__(self):
        msg = ("""
        添加一张新床
        床的尺寸:%s
        床的种类:%s
        """%(self.bed_size, self.bed_type))
        return msg

    def get_bed_size(self):
        return self.bed_size

fangzi = Home(130, "三室一厅", "北京昌平区天通苑")
print(fangzi)
bed1 = Bed(3.5,"三人床")
print(bed1)
fangzi.add_item(bed1)
print(fangzi)
bed1 = Bed(3.5,"三人床")
print(bed1)
fangzi.add_item(bed1)
print(fangzi)  

输出

        住房面积:130
        可用面积:130
        户型:三室一厅
        住房地址:北京昌平区天通苑
        

        添加一张新床
        床的尺寸:3.5
        床的种类:三人床
        

        住房面积:130
        可用面积:126.5
        户型:三室一厅
        住房地址:北京昌平区天通苑
        

        添加一张新床
        床的尺寸:3.5
        床的种类:三人床
        

        住房面积:130
        可用面积:123.0
        户型:三室一厅
        住房地址:北京昌平区天通苑

  

 私有属性和私有方法

 

默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量。
在python中定义私有变量只需要在变量名或函数名前加上 ”__“两个下划线,那么这个函数或变量就是私有的了。
在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername,也就是说,类的内部定义中,
所有以双下划线开始的名字都被"翻译"成前面加上单下划线和类名的形式。
例如:为了保证不能在class之外访问私有变量,Python会在类的内部自动的把我们定义的__spam私有变量的名字替换成为
_classname__spam(注意,classname前面是一个下划线,spam前是两个下划线),因此,用户在外部访问__spam的时候就会
提示找不到相应的变量。   python中的私有变量和私有方法仍然是可以访问的;访问方法如下:
私有变量:实例._类名__变量名
私有方法:实例._类名__方法名()

 

其实,Python并没有真正的私有化支持,但可用下划线得到伪私有。   尽量避免定义以下划线开头的变量!
(1)_xxx      "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量,
需通过类提供的接口进行访问;不能用\'from module import *\'导入
(2)__xxx    类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。),
" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
(3)__xxx__ 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 __init__()代表类的构造函数。

私有属性

class Dog:
    def __init__(self):
        #私有属性
        self.__age = 0

    def set_age(self, new_age):
        if new_age>0 and new_age<=100:
            self.__age = new_age
        else:
            self.age = 0
    def get_age(self):
        return self.__age

dog1 = Dog()
dog1.set_age(-10)
print(dog1.get_age())

  输出

0

 私有方法

class Msg:
    #私有方法
    def __send_msg(self):
        print("正在发送短信...")
    def send_msg(self, new_money):
        if new_money>1000:
            self.__send_msg()
        else:
            print("金额不足请充值")

msg1 = Msg()
msg1.send_msg(100)
msg1.send_msg(10000)

  输出

金额不足请充值
正在发送短信...

  

 __del__方法

class Dog:

    def __del__(self):
        print("---英雄over---")

import sys

dog1 = Dog()
print(sys.getrefcount(dog1))#打印对象的引用个数(结果为2的原因是这个对象还被sys.getrefcount引用了)
dog2 = dog1
print(sys.getrefcount(dog1))

del dog2#不会调用__del__方法,因为这个对象还有其他的变量指向它,即引用计数不是0
print(sys.getrefcount(dog1))
del dog1#此时会调用__del__方法,因为没有变量指向它了
print("================")

#如果在程序结束时,有些对象还存在,那么python解释器会自动调用它们的__del__方法来完成清理工作

  输出

2
3
2
---英雄over---
================

  

重写父类方法

class Animal:
    def eat(self):
        print("-----吃-----")
    def drink(self):
        print("-----喝-----")

class Dog(Animal):
    def bark(self):
        print("-----汪汪叫-----")

class Xiaotq(Dog):
    def fly(self):
        print("-----飞-----")
    #重写父类方法
    def bark(self):
        print("-----狂叫-----")
        # 第一种调用父类被重写的方法
        #Dog.bark(self)
        # 第二种调用父类被重写的方法
        super().bark()

xiaotq = Xiaotq()
xiaotq.bark()

  输出

-----狂叫-----
-----汪汪叫-----

  

  

 

继承

__mro__

Python的每一个有父类的类都有一个与方法解析顺序相关的特殊属性:__mro__, 它是一个tuple, 装着方法解析时的对象查找顺序: 越靠前的优先级越高. 执行下面的代码:

class Base(object):
    def test(self):
        print("-----Base")

class A(Base):
    def test(self):
        print("-----A")

class B(Base):
    def test(self):
        print("-----B")

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

c = C()
c.test()

print(C.__mro__)

  输出

-----A
(<class \'__main__.C\'>, <class \'__main__.A\'>, <class \'__main__.B\'>, <class \'__main__.Base\'>, <class \'object\'>)

  

 

5、派生类可以继承基类中所有的功能

6、派生类和基类同时存在,优先继承派生类。

7、python类可以同时继承多个类(C#/Java不可以)

  优先:自己>左边>右边

class Animals:

    def drink(self):
        print(\'animals drink\')

    def cook(self):
        print(\'animals cook\')

class fish:
    def cook(self):
        print(\'fish cook\')
    def eat(self):
        print(\'fish eat\')

class Dog(Animals,fish):
    def __init__(self,name):
        self.name = name

    def fuck(self):
        print(\'dog fuck\')

    def drink(self):
        print(\'dog drink\')


obj = Dog(\'zhou\')
obj.fuck()
obj.drink()
obj.cook()
obj.eat()

以上代码运行结果:

dog fuck
dog drink
animals cook
fish eat

 

继承顺序(python3.5)

优先:自己>左边>右边>中间

class AB:
    def f1(self):
        print(\'AB\')

class A1(AB):
    def f(self):
        print(\'A1\')

class B1(AB):
    def f(self):
        print(\'B1\')

class A(A1):
    def f(self):
        print(\'A\')

class B(B1):
    def f(self):
        print(\'B\')

class C(A):
    def f(self):
            print(\'C\')

class D(B):
    def f(self):
        print(\'D\')

class E(C,D):
    def f(self):
        print(\'E\')

 

8、多态

  多种形态

  python本身支持多态

  重写,派生类中重新实现基类中的方法

  

class Foo:
    def f1(self):
        print(\'Foo\')

class Bar:
    def f1(self):
        print(\'Bar\')

def func(arg):    //这里的arg可以传不同的对象,这就叫多态
    arg.f1()

func(Foo())
func(Bar())

 

 

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

 

 

 

 

 

 

以上是关于面向对象基础的主要内容,如果未能解决你的问题,请参考以下文章

Python面向对象学习之八,装饰器

Java基础:封装

面向对象基础

Python基础 面向对象

python基础之面向对象

Python面向对象基础