面向对象是一种程序设计思想,对象作为程序基本单元,包含了数据和操作数据的函数。

面向对象的三大特点--数据封装、多态和继承。

  1. #类的创建,class关键字,类名大写,object表示从哪个类继承而来,如果没有继承的类,默认就是object,这是所有的类都会继承的类
  2.  
  3. class Student(object):
  4. pass

创建类的实例

  1. tom = Student() #tom实例指向类Student

还可以自由的为实例绑定属性

  1. tom.age = 18
  2. tom.sex = boy
  3.  
  4. #访问实例属性
    >>>tom.age
    18
    >>>tom.sex
    'boy'

类是一个模板,可以在创建类的同时将实例的属性绑定

  1. class Student(object):
  2. def __init__(self,name,age,sex): #__init__方法可以将实例属性绑定,第一个参数永远是self,表示实例本身,这样,age、sex属性绑定后指向实例本身
  3.      self.name=name
    self.age=age
  4. self.sex=sex

使用__init__方法后,再去创建实例时,属性就不允许为空,否则提示丢失需求参数

  1. tom = Student('tom',20,'boy')
  2. >>>tom.name
  3. tom
  4. >>>tom.age
  5. 20
  6. >>>tom.sex
  7. 'boy'
  8.  
  9. >>>tom = Student()
    TypeError: __init__() missing 3 required positional arguments: 'name', 'age', and 'sex'

实例的属性可以在外部随意访问,也可以再外部定义一个函数用来访问类实例全部的属性。

  1. #外部直接访问
    >>>print(tom.name)
    tom
    ......
  2.  
  3. #外部函数访问
    def info(stu):
  4. print('%s\n%d\n%s\n' %(stu.name,stu.age,stu.sex))
  5.  
  6. >>>tom = Student('tom',20,'boy')
  7.  
  8. >>>info(tom)
  9.  
  10. tom
  1. 20
  2. boy

数据封装

像上面在外部定义访问函数不是不可以的。但类本身具有这些属性,直接在类内部写出打印函数就行  这样就实现了数据的封装。

完整的封装

  1. class Student(object):
  2. def __init__(self,name,age,sex):
  3. self.name=name
  4. self.age=age
  5. self.sex=sex
  6. def info(self):
  7. print('%s\n%d\n%s' %(self.name,self.age,self.sex))
  8.  
  9. tom = Student('tom',20,'boy')
  10.  
  11. >>>tom.info()
    tom
    20
    boy

这样写出来,对象属性及操作方法对外隐藏了,调用很简单。

同时封装的好处就是可以为类增加新的方法,比如内部定义一个函数来判定学生属于的班级。

  1. class Student(object):
  2. def __init__(self,name,stunum):
  3. self.name=name
  4. self.stunum=stunum
  5.  
  6. def info(self):
  7. print('%s%s' %(self.name,self.stunum))
  8.  
  9. def attclass(self): #新增加的方法,根据学号判断所属班级
  10. if self.stunum > 0 and self.stunum <= 50:
  11. print("class one")
  12. if self.stunum > 50 and self.stunum <=100:
  13. print("class two")
  14. print("class three")
  15.  
  16. >>>tom = Student('tom',56)
    >>>tom.info()
    tom
    56
    >>>tom.attclass()
    class two

私有变量

从上面的代码看,不仅在外部可以直接访问实例的属性,还可以随便的更改实例的属性,如何使属性变成私有属性,不能随便更改和访问?

要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private)

  1. class Student(object):
  2. def __init__(self,name,num,age,sex):
  3. self.__name=name #声明为私有变量,下同
  4. self.__num=num
  5. self.__age=age
  6. self.__sex=sex
  7.  
  8. def print_std(self):
  9. print('name:%s\nstunum:%d\nage:%d\nsex:%s\n' %(self.__name,self.__num,self.__age,self.__sex))
  10.  
  11. def attclass(self):
  12. if self.__num >0 and self.__num <= 50:
  13. print('class one')
  14. elif self.__num >50 and self.__num <= 100:
  15. print('class two')
  16. else:
  17. print('class three')
  18.  
  19. tom = Student('tom',65,20,'boy')
  20.  
  21. tom.num=20 ###私有变量外部更改失效,失效不会有错误提示,编译器直接略过
  22.  
  23. tom.print_std()
  24.  
  25. tom.attclass()
  26. print(tom.__name)#访问时报错,AttributeError: 'Student' object has no attribute '__name'

如果想要外部代码拿到属性怎么做?

为类增加一个函数,函数直接返回实例属性

  1. class Student(object):
  2. pass
  3.  
  4. def get_name(self):
  5. return self.__name
  6. def get...():
           return .....

如何允许外部代码修改属性?

为类增加一个函数,函数参数添加上要修改的属性,这样设置不仅可以避免参数的无效,还可以增加方法约束参数。

  1. class Student(object):
  2. pass
  3.  
  4. def set_name(self,name):
  5. self.__name=name
  6. .....
  7.  
  8. >>>tom = Student('tom'..)
  9.  
  10. >>>tom.set_name('jerry')
  11.  
  12. >>>print(tom.get_name())
  13. jerry

所以,总结下来:

当类的属性没有声明为私有变量时,类的方法(内部函数)可以修改和访问;外部实例和函数可以随便修改访问。

当类的属性声明为私有变量时,类的方法可以修改和访问;外部实例和函数无法修改和访问。

在Python中,当有__xxx__,以双下划线开头并以双下划线结束的变量名称时,是可以访问的,所以,不要和私有的变量命名方式混淆了。

当类中定义有以单下划线开头的变量时,如_num这样的,是可以外部访问的,但是按照规范来说,最好是不要在外部访问。

不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:tom._Student_name

类的继承

当已有定义好的父类时,再去定义一个类就可以从已定义好的继承,叫做子类。

继承最大的好处就是父类的方法被子类全部继承

  1. class Food(object):
  2. def color(self):
  3. print('yello')
  4.  
  5. class Banana(Food):
  6. pass
  7.  
  8. >>>ban=Banana()#创建Banana实例
    >>>ban.color()
    yellow

同时可以自己定义子类的其他方法

  1. class Banana(Food):
  2. def feture(self,fet):
  3. self.fet=fet
  4.  
  5. >>>ban=Banana()
  6.  
  7. >>>ban.feture('sweet')
  8. >>>ban.fet
    sweet

当子类与父类方法相同时,父类方法被覆盖。

  1. class Food(object):
  2. def color(self):
  3. print('yellow')
  4.  
  5. class Banana(Food):
  6. def color(self):
  7. print('good')
  8.  
  9. >>>ban=Banana()
  10. >>>ban.color()
  11. good

这样就得到了继承的另一个好处,多态。

Python允许多重继承,

class Person(class1,class2....):

  pass

子类拥有所有父类的功能。

多态

当定义一个类时,就是定义了一种数据类型,使用isinstance()判断,实例ban即属于Banana类型,又属于Food类型,方向向上,反之不行。香蕉是食物,食物不一定是香蕉。

  1. class Person(object):
  2. def __init__(self,name,age):
  3. self.name=name
  4. self.age=age
  5. def say(self):
  6. print('i am %s' %self.name)
  7.  
  8. class Student(Person):
  9. def __init__(self,name,age):
  10. self.name=name
  11. self.age=age
  12.  
  13. def info(self):
  14. print('%s\n%d\n' %(self.name,self.age))
  15.  
  16. def info_pr(name):
  17. return name.say()
  18.  
  19. >>>tom = Student('tom',20)
  20.  
  21. >>>info_pr(tom)
    i am tom

方法调用将作用在name的实际类型上,先查找Student自身的定义,找不随继承树向上查找,直到找到方法后停止。

对于静态语言而言,想要传入Person类型,必须是Person或者Person的子类,不然无法使用say()方法

对于动态语言,只要传入的对象有say()的方法。

动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。

实例属性和类的属性

给实例绑定属性是通过实例变量或者self绑定,而给类绑定属性实在class中直接定义的。

  1. class Student(student):
  2. name='Student'
  3. pass
  4.  
  5. #通过这种方式绑定类的属性,外部的实例是可以修改和访问的,如果实例属性和类的属性名称一致时,实例的优先级时大于类的属性的,外部访问先寻找实例属性,找不到再去寻找类的属性。
    >>>s = Student()
    >>>print(s.name)
    Student
  6.  
  7. >>>print(Student.name)打印类的name属性
    Student
  8.  
  9. >>>s.name='tom' 给实例的name属性绑定‘tom
    >>>print(s.name)
    tom
  10.  
  11. >>>print(Student.name)
    Student #类的属性依然存在

Python面向对象编程-类的封装,继承、多态的更多相关文章

  1. 1.Java基础-面向对象编程思想(封装继承多态接口)

    封装: 1.定义:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别. 2.封装的目的是:增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的 ...

  2. Python - 面向对象编程 - 三大特性之继承

    继承 继承也是面向对象编程三大特性之一 继承是类与类的一种关系 定义一个新的 class 时,可以从某个现有的 class 继承 新的 class 类就叫子类(Subclass) 被继承的类一般称为父 ...

  3. Python面向对象编程 -- 类和实例、访问限制

    面向对象编程 Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程 ...

  4. Python 面向对象编程——类定义与对象

    <类定义与对象声明> 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对 ...

  5. python -- 面向对象编程(类、对象)

    一.类 类是用来描述具有相同的属性和方法的对象的集合. 它定义了该集合中每个对象共同拥有的属性和方法. 类是一个独立的单位,它有一个类名,其内部包括成员变量和成员方法,分别用于描述对象的属性和行为. ...

  6. python3 面向对象编程--类的封装和继承

    #python3import refrom urllib import requestimport os class PosterSpider(object):     def __init__(se ...

  7. java类的封装 继承 多态

    1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ pub ...

  8. java面向对象(封装-继承-多态)

    框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...

  9. Python面向对象编程(下)

    本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...

随机推荐

  1. 【Ruby】【高级编程】正则

    #[[正则]]=beginsub 和 gsub 及它们的替代变量 sub! 和 gsub! 是使用正则表达式时重要的字符串方法.所有这些方法都是使用正则表达式模式执行搜索与替换操作.sub 和 sub ...

  2. 获取IP及判断IP是否在区间

    /// <summary> /// 获取客户端IP /// </summary> /// <returns></returns> public stat ...

  3. bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 7925  Solved: 2975[Submit][Status ...

  4. jmeter3.2 版本完美实现Load Test报表

    今天下载了最新版的apache tomcat jmeter 3.2,需要jdk1.8以上的版本. 用非GUI模式运行压力测试后,出现的报表太完美了. 将jmx脚本放在就jmeter_home/bin下 ...

  5. Asp.net core 学习笔记 ( Identity 之 Authentication )

    和从前的 identity 区别不是很大. 从 2.1 开始 vs 模板的 identity 都被封装了起来, 你几乎看不到任何一行代码, 需要向下面这样打开它, 才能做修改. 说一下比较常用的配置 ...

  6. Eclipse无法使用springboot2.x

    <!-- 阿里云提供的镜像地址 --> <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mir ...

  7. boke练习: spring boot: security post数据时,要么关闭crst,要么添加隐藏域

    spring boot: security post数据时,要么关闭crst,要么添加隐藏域 http.csrf().disable(); 或者: <input name="${_cs ...

  8. 雷林鹏分享:XML 注意事项

    XML 注意事项 这里列出了您在使用 XML 时应该尽量避免使用的技术. Internet Explorer - XML 数据岛 它是什么?XML 数据岛是嵌入到 HTML 页面中的 XML 数据. ...

  9. every day a practice —— morning(2)

    Two years at sea have fostered a close relationship between the two fellow sailors as they cross the ...

  10. 【异常及源码分析】org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping

    一.异常出现的场景 1)异常出现的SQL @Select("SELECT\n" + " id,discount_type ,min_charge, ${cardFee} ...