天天看点

python面对对象三大特性

面对对象三大特性是:封装,继承,多态      
  • 封装:

    也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。

  • 继承:

    是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;

  • 多态:

    就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

  • 1.继承的概述和定义格式

    继承:

    子类继承父类,子类一旦继承父类,就拥有父类中非私有的属性和方法.

    2.object类的介绍

object类:
  是所有类的父类,任何一个类默认都是继承object类.      

3.子类不能继承父类中私有的属性和方法

class Father:

    def __init__(self, money, house):
        self.money = money
        self.house = house
        # 私有属性
        self.__girl_friend = "ViVi"

    def run_company(self):
        print("父亲经营公司...")

    # 私有方法
    def __tla(self):
        print(f"父亲与{self.__girl_friend}谈恋爱...")


# 子类继承父类
class Son(Father):
    def test(self):
        # print(self.__girl_friend)
        self.__tla()


s = Son(200000000, "前门大街300平米的一套四合院")
print(s.money)
print(s.house)
s.run_company()

# print(s.__girl_friend)
s.test()      

4.子类中重写父类中的方法

"""
重写父类中的方法的原因:
    父类中的方法不能满足子类的需要,但是子类又想保留这个方法名.
重写父类中的方法:
    这就需要在子类中定义一个同名的方法,这叫重写父类中的方法.
如何重写:
    1.把父类中的方法复制粘贴到子类中
    2.在子类中修改方法体

特点:
    子类重写了父类中的方法后,当通过子类对象调用这个方法时,调用的是子类中的这个方法.
"""


class Father: # class Father(object):

    def __init__(self, money, house):
        self.money = money
        self.house = house

    def run_company(self):
        print("父亲经营公司...")


# 子类继承父类
class Son(Father):
    # 重写了父类中的run_company方法
    def run_company(self):
        print("儿子经营公司...")



s = Son(200000000, "前门大街300平米的一套四合院")
print(s.money)
print(s.house)
s.run_company()      

5.在子类中调用父类中被重写的方法

"""
调用 父类中的被重写的run_company方法,有三种格式:
    1.父类名.方法名(self, 实参1,实参2,...)
    2.super(子类名,self).方法名(实参1,实参2,...)
    3.super().方法名(实参1,实参2,...)
"""
class Father: # class Father(object):

    def __init__(self, money, house):
        self.money = money
        self.house = house

    def run_company(self):
        print("父亲经营公司...")


# 子类继承父类
class Son(Father):
    # 重写了父类中的run_company方法
    def run_company(self):
        print("儿子经营公司...")

    def test(self):
        # 调用的是子类中的run_company方法
        # self.run_company()

        # 调用 父类中的run_company方法
        # 1.父类名.方法名(self, 实参1,实参2,...)
        # Father.run_company(self)
        # 2.super(子类名,self).方法名(实参1,实参2,...)
        # super(Son, self).run_company()
        # 3.super().方法名(实参1,实参2,...)
        super().run_company()

s = Son(200000000, "前门大街300平米的一套四合院")
s.test()      

6.继承中的两个细节

1.如何在子类中访问中的私有属性和私有方法

class Father:

    def __init__(self, money, house):
        self.money = money
        self.house = house
        # 私有属性
        self.__girl_friend = "ViVi"

    def run_company(self):
        print("父亲经营公司...")

    # 私有方法
    def __tla(self):
        print(f"父亲与{self.__girl_friend}谈恋爱...")

    def test(self):
        """
        访问私有属性和方法
        """
        print(f"儿子像跟{self.__girl_friend}说句话...")
        self.__tla()


# 子类继承父类
class Son(Father):
    def la(self):

        # 调用从父类中继承的test方法
        self.test()


s = Son(200000, "5套别墅")
s.test()
# 如上代码,儿子通过继承父亲的方法找到了父亲的小娘子搞了事情      
class Father:

    def __init__(self, money, house):
        self.money = money
        self.house = house

    def run_company(self):
        print("父亲经营公司...")


class Son(Father):
    # 重写了父类中的init方法
    def __init__(self, name, money, house):
        self.name = name
        # 使用第三种格式调用父类中的__init__方法
        super().__init__(money, house)


s = Son("聪聪", 2000000000, "5套别墅")
print(s.name)
print(s.money)
print(s.house)      

​ 2.如果子类中也定义了__init__方法,子类如何继承父类中定义的属性

self.name = name      

7.多层继承

一层一层的继承;      

8.多继承的格式

一个子类同时继承多个父类.

多继承的格式:

  class 子类名(父类1, 父类2, ...):
    子类中的代码      

9.多继承-父类中有相同init的方法

"""
多继承的格式:

    class 子类名(父类1, 父类2, ...):
        子类中的代码
"""
class A:
    def __init__(self, a):
        self.a = a

    def methodA(self):
        print("---------methodA---------")

    def show(self):
        print("show from A")


class B:
    def __init__(self, b):
        self.b = b

    def methodB(self):
        print("---------methodB---------")

    def show(self):
        print("show from B")


# 让C类同时继承A,B两个父类
class C(A, B):

    # 为了继承A,B两个父类中的属性,需要重写init方法,在方法中调用两个父类中的init方法
    def __init__(self, a, b):
        # 调用A,B类中的init方法
        A.__init__(self, a)
        B.__init__(self, b)


c = C("a的属性", "b的属性")

print(c.a)
print(c.b)

c.methodA()
c.methodB()
c.show()      

10.多继承-调用指定父类中的方法

"""
多继承的格式:

    class 子类名(父类1, 父类2, ...):
        子类中的代码
"""
class A:
    def __init__(self, a):
        self.a = a

    def methodA(self):
        print("---------methodA---------")

    def show(self):
        print("show from A")


class B:
    def __init__(self, b):
        self.b = b

    def methodB(self):
        print("---------methodB---------")

    def show(self):
        print("show from B")


# 让C类同时继承A,B两个父类
class C(A, B):

    # 为了继承A,B两个父类中的属性,需要重写init方法,在方法中调用两个父类中的init方法
    def __init__(self, a, b):
        # 调用A,B类中的init方法
        A.__init__(self, a)
        B.__init__(self, b)

    def test(self):
        # 调用A类中的show方法
        # self.show()
        A.show(self)
        # 调用B类中的方法
        B.show(self)


c = C("a的属性", "b的属性")

c.test()      

11.实例属性和实例方法

实例:
  就是对象.
  
实例对象:
  通过类名 创建的 对象.      

实例属性:

给实例对象添加的属性.
  
  实例属性是存储实例对象里面的.
  
  实例属性 是 属于 实例对象的.
  
实例方法:

  第一个形参是self的方法.
  尽管实例方法 是 存储在 类里面的,但是它 属于 实例对象.
  
实例属性和实例方法,都必须通过实例对象访问.      

12.类对象 类属性

类对象:
  也是一个对象.
  
  一个类 就是一个 类对象.
  类对象的名字 就是 类的 名字.      

类属性:

也是 一种 属性.

它存储的数据,是所有的实例对象共享共用的数据,不属于某一个实例对象专有.是所有的实例对象共有的.

当这个数据 是所有的实例对象共享共用时,才使用 一个类属性 存储这个数据.
  
定义类属性的格式:
  在类的里面,方法的外面定义的属性(变量).      

13.类方法

"""

"""



class Student:

    __kongtiao = "格力空调"

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    """
    定义类方法:
        1.在方法定义的那一行的上面,使用@classmethod装饰器
            这个装饰器的作用:
                1.用来表示下面的方法是一个类方法的
                2.在调用类方法时,python解释器会自动把类名传递cls
        2.第一个形参必须是cls,表示类对象,就是那个类名
        
    访问方式:
        1.实例对象.类方法名(实参1,实参2,...)
        2.类对象.类方法名(实参1,实参2,...)(推荐的方式)
    特点:
        1.在调用类方法时,python解释器会自动把类对象传递给cls
        2.只能访问类属性或者类方法,不能访问实例属性或者实例方法
        
    什么时候定义一个类方法?
        在方法中只需要访问类属性或者类方法,不访问实例属性或者实例方法.
    """
    @classmethod
    def study(cls):
        print(cls.__kongtiao)
        cls.show()

    @classmethod
    def show(cls):
        print("我是类方法...")


# 1.实例对象.类方法名(实参1,实参2,...)
s = Student("张柏芝", 38, "女")
s.study()
# 2.类对象.类方法名(实参1,实参2,...)
Student.study()      

14.静态方法

class Student:

    __kongtiao = "格力空调"

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    """
    定义静态方法的步骤:
        1.在方法定义的那一行的上面,使用@staticmethod装饰器
            1.标识下面的方法时静态方法
        2.方法的第一个形参,既不是self也不是cls.
        
    特点:
        在方法中不能访问实例属性和实例方法了,因为在它里面得不到self
        通常在这个方法中不访问实例属性和实例方法也不访问类属性和类方法.
        
    访问方式:
         1.实例对象.类方法名(实参1,实参2,...)
         2.类对象.类方法名(实参1,实参2,...)(推荐的方式)
         
    在什么时候定义静态方法?
        当在这个方法中既不访问实例属性实例方法,也不访问类属性类方法时.
    """
    @staticmethod
    def study():
        print("挖掘技术哪家强,")
        print("欲学技术到蓝翔.")
        print("学完技术包分配,")
        print("尼玛还是富士康!")

    def test(self):
        jingtai.EncodeUtils.encode("hello", "utf-8")
        self.study()
        Student.study()

# 1.实例对象.类方法名(实参1,实参2,...)
s = Student("张柏芝", 38, "女")

# s.study()
# Student.study()

s.test()      
# 定义父类
class Father:
    def cure(self):
        print("父亲给病人治病...")


# 定义子类继承父类
class Son(Father):
    # 重写父类中的方法
    def cure(self):
        print("儿子给病人治病...")


"""

鸭子类型:
    
"""

# 定义函数,在里面 调用 医生的cure函数
def call_cure(doctor):

    # 调用医生治病的方法
    doctor.cure()


# 创建父类对象
father = Father()
# 调用函数,把父类对象传递函数
call_cure(father)


# 创建子类对象
son = Son()
# 调用函数,把子类对象传递函数
call_cure(son)      
把8个老师 随机分配到 3个办公室.