博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初学Python的学习笔记8----面向对象、数据封装、访问限制、继承和多态
阅读量:7087 次
发布时间:2019-06-28

本文共 4275 字,大约阅读时间需要 14 分钟。

hot3.png

1.面向对象: 类(Class):类是抽象的模板 实例(Instance):实例是根据类创建出来的一个个具体的“对象”,每个对象具有相同的方法,但是数据可能不一样

(1)定义类: class className(object): pass 类名通常是大写的字母开头,参数是object,表示该类是从哪一个类上面继承下来的 (2)创建实例:类名+() (3)给实例变量绑定属性:实例名.属性 = 属性值 通过__init__方法,self表示实例本身,调用函数的时候不需要传递进去

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

2.数据封装:直接在类的内部定义访问数据的函数,用类的方法去访问这些参数

class Student(object):    def __init__(self,name,score):        self.name = name        self.score = score    def print_score(self):        print('%s: %s' % (self.name, self.score))bart = Student('YJ',100)bart.print_score()

(1)数据封装的另一个好处是可以给类增加新的方法

class Student(object):    def __init__(self,name,score):        self.name = name        self.score = score    def print_score(self):        print('%s: %s' % (self.name, self.score))    def get_grade(self):        if self.score >= 90:            return 'A'        elif self.score >= 60:            return 'B'        else:            return 'C'bart = Student('YJ',100)bart.get_grade()

PS:对于两个实例变量,虽然他们都是同一个类的不同实例,但是拥有的变量名称可以不一样

yj = Student('YJ',100)lp = Student('LP',101)yj.age = 24print yj.age    # 24print lp.age    # 报错

3.访问限制 为了让内部属性不被外部方法去访问,可以在属性的名称前面加上__两个下划线,就变成了一个私有变量,只有内部访问,外部不能访问

class Student(object):    def __init__(self, name, score):        self.__name = name        self.__score = score    def print_score(self):        print('%s: %s' % (self.__name, self.__score))

修改之后外部已经不能去访问这两个属性

yj = Student('YJ',100);print yj.__name     # 报错

PS:确保外部代码不能随意修改对象内部的代码,通过访问限制的保护,代码更加健壮

给类添加get_name和get_score方法来获取name和score

class Student(object):    def __init__(self, name, score):        self.__name = name        self.__score = score    def print_score(self):        print('%s: %s' % (self.__name, self.__score))    def get_name(self):        return self.__name    def get_score(self):        return self.__score

在类里面定义方法的好处是可以对参数做检查,避免传入无效的参数 添加设置score的方法

class Student(object):    def __init__(self, name, score):        self.__name = name        self.__score = score    def print_score(self):        print('%s: %s' % (self.__name, self.__score))    def get_name(self):        return self.__name    def get_score(self):        return self.__score    def set_score(self,score):        if 0 <= score <= 100:            self.__score = score        else:            raise ValueError('bad score')

PS:在Python中,变量名是__xx__,这种是特殊变量,是可以直接访问的,不是私有变量,所以不能这样去命名 __xx这样的变量外部是可以访问的,但是一般当做私有变量,最好不要这样做

一个错误写法:

lp = Student('LP', 101) print lp.get_name()    # LP lp.__name = 'new' print lp.__name    # new

PS:表面上看外部代码成功的修改了name,实际上这个__name变量和class内部的__name变量不是一个变量 class内部的变量已经被Python解释器自动改成了_类名_name,而外部代码只是给lp这个实例对象新增加了一个__name变量

print lp.get_name()    # LP

4.继承和多态 继承:定义一个class的时候,可以从某个现有的class继承,新的class被称为子类(Subclass),被继承的class被称为基类(Base class)、父类()、超类(Super class) (1).继承的一个好处就是子类获得了父类的全部功能

class Animal(object):   def run(self):       print('Animal is running...')class Dog(Animal):    passclass Cat(Animal):    passdog = Dog()dog.run()cat = Cat()cat.run()

(2).继承的第二个好处:多态

class Animal(object):   def run(self):       print('Animal is running...')class Dog(Animal):   def run(self):   # 覆盖了父类的run()        print('Dog is running...')   def eat(self):        print('Cat is running...')class Cat(Animal):   def run(self):   # 覆盖了父类的run()        print('Cat is running...')dog = Dog()dog.run()cat = Cat()cat.run()

(3)定义一个class的时候,实际上就定义了一种数据类型 用isinstance()判断一个变量是否是某个类型

a = list()  # a是list类型isinstance(a, list)

如果一个实例对象的数据原型是某个子类,那他的数据类型也可以被看做是父类

dog = Dog()isinstance(dog, Animal)

但是反过来不可以

animal = Animal()instance(animal, Dog)

(4)一个函数可以接受animal实例

class Animal(object):   def run(self):       print('Animal is running...')class Dog(Animal):   def run(self):   # 覆盖了父类的run()        print('Dog is running...')   def eat(self):        print('Cat is running...')class Cat(Animal):   def run(self):   # 覆盖了父类的run()        print('Cat is running...')class Tortoise(Animal):    def run(self):        print("Tortoise is running slowly...")def run_twice(insObj):    animal.run()    animal.run()run_twice(Animal())

PS:多态:传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run() "开闭"原则: 对扩展开放:允许新增Animal子类; 对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

(5).静态语言:如果需要传入Animal类型,则传入的对象必须是Animal类型 动态语言:不一定需要传入Animal类型,只需要保证传入的对象有一个run()

转载于:https://my.oschina.net/yj1993/blog/1572913

你可能感兴趣的文章
OpenExpressApp 框架结构(2)
查看>>
read和变量设定方式
查看>>
利用UltraISO制作RedhatU盘启动盘
查看>>
什么是高内聚、低耦合?
查看>>
g++编译过程和动态链接库
查看>>
java在线预览txt、word、ppt、execel,pdf代码
查看>>
元素始终居浏览器窗口中间的位置
查看>>
Linux的常用目录(Ubuntu)
查看>>
Completely Uninstall Node.js from Mac OS X
查看>>
如何将Windows XP SP3改成SP2
查看>>
【远程医疗专题】远程医疗论文30篇及解决方案10篇
查看>>
IPSec实验的一些体会
查看>>
c中static作用
查看>>
给初学者的RxJava2.0教程(三)(转)
查看>>
探究ConcurrentHashMap中键值对在Segment[]的下标如何确定
查看>>
Docker学习记录3: 搭建 Private Registry
查看>>
计算机图形学 补 光线跟踪
查看>>
spring整合logback配置文件
查看>>
captive portal
查看>>
mysql基本数据类型(mysql学习笔记三)
查看>>