零基础小白入门Python之文件读写(二)

封装、继承和多态

面向对象编程有三大重要特征:封装、继承和多态。

封装

封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现,外界只能通过 接口使用该对象,而不能通过任何形式修改对象内部实现,正是由于封装机制,程序在使用某一对象时不需要关 心该对象的数据结构细节及实现操作的方法。使用封装能隐藏对象实现细节,使代码更易维护,同时因为不能直 接调用、修改对象内部的私有信息,在一定程度上保证了系统安全性。类通过将函数和变量封装在内部,实现了 比函数更高一级的封装。

class Student: 
    room = '101' 
    address = 'changsha' 

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

    def print_age(self): 
        print('%s: %s' % (self.name, self.age)) 

# 以下是错误的用法 
# 类将它内部的变量和方法封装起来,阻止外部的直接访问 
print(room) 
print(adress) 
print_age()

点击获取全套Python零基础入门资料

继承

继承来源于现实世界,一个最简单的例子就是孩子会具有父母的一些特征,即每个孩子都会继承父亲或者母亲的 某些特征,当然这只是最基本的继承关系,现实世界中还存在着更复杂的继承。继承机制实现了代码的复用,多 个类公用的代码部分可以只在一个类中提供,而其他类只需要继承这个类即可。

继承最大的好处是子类获得了父类的全部变量和方法的同时,又可以根据需要进行修改、拓展。其语法结构如 下:

class Foo(superA, superB,superC....): 
class DerivedClassName(modname.BaseClassName): ## 当父类定义在另外的模块时

Python支持多父类的继承机制,所以需要注意圆括号中基类的顺序,若是基类中有相同的方法名,并且在子类使 用时未指定,Python会从左至右搜索基类中是否包含该方法。一旦查找到则直接调用,后面不再继续查找。

# 父类定义 
class people: 

    def __init__(self, name, age, weight): 
        self.name = name 
        self.age = age 
        self.__weight = weight 

     def speak(self): 
         print("%s 说: 我 %d 岁。" % (self.name, self.age)) 

# 单继承示例 
class student(people): 

    def __init__(self, name, age, weight, grade): 
        # 调用父类的实例化方法 
        people.__init__(self, name, age, weight) 
        self.grade = grade 
        
       # 重写父类的speak方法 
       def speak(self): 
           print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.gra de)) 

s = student('ken', 10, 30, 3) 
s.speak()

Python3的继承机制

Python3的继承机制不同于Python2。其核心原则是下面两条,请谨记!

  • 子类在调用某个方法或变量的时候,首先在自己内部查找,如果没有找到,则开始根据继承机制在父类里查 找。

  • 根据父类定义中的顺序,以深度优先的方式逐一查找父类!

super()函数

我们都知道,在子类中如果有与父类同名的成员,那就会覆盖掉父类里的成员。那如果你想强制调用父类的成员 呢?使用super()函数!这是一个非常重要的函数,最常见的就是通过super调用父类的实例化方法 :

__init__

语法:

 super(子类名, self).方法名()

需要传入的是子类名和self,调用的是父类里的方法,按父类的 方法需要传入参数。要传入的是子类名和self,调用的是父类里的方法,按父类的 方法需要传入参数。

class A: 
    def __init__(self, name): 
        self.name = name 
        print("父类的__init__方法被执行了!") 
    def show(self): 
        print("父类的show方法被执行了!") 

class B(A): 
    def __init__(self, name, age): 
        super(B, self).__init__(name=name) 
        self.age = age 

    def show(self): 
        super(B, self).show() 

obj = B("jack", 18) 
obj.show()

多态
先看下面的代码:

class Animal: 

    def kind(self): 
        print("i am animal") 

class Dog(Animal): 

    def kind(self): 
        print("i am a dog")

class Cat(Animal): 

    def kind(self): 
        print("i am a cat") 

class Pig(Animal): 

    def kind(self): 
        print("i am a pig") 

# 这个函数接收一个animal参数,并调用它的kind方法 
def show_kind(animal): 
    animal.kind() 


d = Dog() 
c = Cat() 
p = Pig() 

show_kind(d) 
show_kind(c) 
show_kind(p) 

------------------ 

打印结果: 
i am a dog 
i am a cat 
i am a pig

狗、猫、猪都继承了动物类,并各自重写了kind方法。show_kind()函数接收一个animal参数,并调用它的kind 方法。可以看出,无论我们给animal传递的是狗、猫还是猪,都能正确的调用相应的方法,打印对应的信息。这 就是多态。

实际上,由于Python的动态语言特性,传递给函数show_kind()的参数animal可以是 任何的类型,只要它有一 个kind()的方法即可。动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动 态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它 就可以被看做是鸭子。

成员保护和访问限制

在类的内部,有各种变量和方法。这些数据成员,可以在类的外部通过实例或者类名进行调用,例如:

class People: 
    title = "人类" 

    def __init__(self, name, age): 
        self.name = name 
        self.age = age 
  
    def print_age(self): 
        print('%s: %s' % (self.name, self.age)) 

obj = People("jack", 12) 
obj.age = 18 
obj.print_age() 
print(People.title)

上面的调用方式是我们大多数情况下都需要的,但是往往我们也不希望所有的变量和方法能被外部访问,需要针 对性地保护某些成员,限制对这些成员的访问。这样的程序才是健壮、可靠的,也符合业务的逻辑。

在类似JAVA的语言中,有private关键字,可以将某些变量和方法设为私有,阻止外部访问。但是,Python没有 这个机制,Python利用变量和方法名字的变化,实现这一功能。

点击获取全套Python零基础入门资料

在Python中,如果要让内部成员不被外部访问,可以在成员的名字前加上两个下划线 __ ,这个成员就变成了 一个私有成员(private)。私有成员只能在类的内部访问,外部无法访问。

class People: 
    title = "人类"
    def __init__(self, name, age): 
        self.__name = name 
        self.__age = age 

    def print_age(self): 
        print('%s: %s' % (self.__name, self.__age)) 

obj = People("jack", 18) 
obj.__name 

------------------------------ 
Traceback (most recent call last): 
  File "F:/Python/pycharm/201705/1.py", line 68, in <module> 
    obj.__name 
AttributeError: 'People' object has no attribute '__name'

那外部如果要对 __name 和 __age 进行访问和修改呢?在类的内部创建外部可以访问的get和set方法!

class People: 
    title = "人类" 

    def __init__(self, name, age): 
        self.__name = name 
        self.__age = age 
 
    def print_age(self): 
        print('%s: %s' % (self.__name, self.__age)) 

    def get_name(self): 
        return self.__name 

    def get_age(self): 
        return self.__age 

    def set_name(self, name): 
        self.__name = name 

    def set_age(self, age): 
        self.__age = age 

obj = People("jack", 18) 
obj.get_name() 
obj.set_name("tom")

这样做,不但对数据进行了保护的同时也提供了外部访问的接口,而且在 get_name , set_name 这些方法 中,可以额外添加对数据进行检测、处理、加工、包裹等等各种操作,作用巨大!

类的成员与下划线总结:
在这里插入图片描述

特殊成员和魔法方法

Python中有大量类似 __doc__ 这种以双下划线开头和结尾的特殊成员及“魔法方法”,
它们有着非常重要的 地位和作用,也是Python语言独具特色的语法之一!

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值