【九】面向对象

一:使用class定义类

假设你要定义一下对象用于记录联系人,每个对象对应一个人,首先需要定义person类作为生产对象的模具。

首先创建一个没有任何内容的空类:

In [301]: class person():
     ...:     pass

二:对类进行初始化

init()是python中一个特殊的函数名,用户根据类的定义创建实例对象,self参数指向了这个正在被创建对象本身

#定义一个person类
#给person类创建一个初始化函数
In [302]: class person():
     ...:     def __init__(self,name):
     ...:         self.name=name
     ...:         

用person类创建一个对象,为name特性传递一个字符串参数:

#python执行:person.__init__(huahua,"cmf"),self代表实例化的对象,这个例子指的是huahua
In [304]: huahua=person("cmf")
In [305]: huahua.name
Out[305]: ‘cmf‘

上述代码做了如下工作:

  1. 查看person类的定义
  2. 在内存中实例化一个新的对象
  3. 调用对象的init方法,将这个新创建的对象作为self传入,并将并一个参数cmf作为name传入
  4. 将name的值存入对象
  5. 返回这个新的对象
  6. 将huahua与这个对象关联

三:继承

利用类的继承,从已有类中衍生出新的类,添加和修改部分功能。使用继承得到的新类会自动获取旧类中的很多方法,从而不需要复制

#创建一个person类
In [306]: class person():
     ...:     pass
#创建一个testperson类,继承person
     ...: class testperson(person):
     ...:     pass 

接着,为每个类创建一个实例对象:

In [307]: ren=person()
In [308]: test1=testperson()

子类是父类的一种特殊情况,它属于父类

#创建父类
In [310]: class person():
     ...:     def exclain(self):
     ...:         print("i am a person")
     ...:
#创建子类,并继承父类
In [311]: class testperson(person):
     ...:     pass
     ...:
#实例化
In [312]: ren=person()
In [313]: test=testperson()
#调用父类的方法
In [314]: ren.exclain()
i am a person
#调用父类的方法
In [315]: test.exclain()
i am a person

四:覆盖方法

新创建的子类会自动继承父类的所有信息,接下来我们来看看子类如何替代(覆盖)父类的方法

In [316]: class person():
     ...:     def exclain(self):
     ...:         print("i am a person")
     ...:
#创建一个新的同名方法,覆盖父类方法
In [317]: class testperson(person):
     ...:     def exclain(self):
     ...:         print("i am a testperson")
     ...:
     ...:
In [318]: ren=person()
In [319]: test=testperson()
In [320]: ren.exclain()
i am a person
In [321]: test.exclain()
i am a testperson

为子类添加新方法

In [325]: class person():
     ...:     def __init__(self,name):
     ...:         self.name=name
     ...:
     ...:
In [326]: class testperson(person):
     ...:     def __init__(self,name,email):
     ...:         super().__init__(name) #super:继承父类的name方法
     ...:         self.email=email
     ...:
In [327]: test=testperson("test","[email protected]")
In [328]: test.name
Out[328]: ‘test‘
In [329]: test.email
Out[329]: ‘[email protected]‘
In [330]: ren=person("ren")
In [331]: ren.name
Out[331]: ‘ren‘
#父类不能访问子类特有的方法
In [332]: ren.email
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-332-0d7ad82f0acc> in <module>()
----> 1 ren.email

AttributeError: ‘person‘ object has no attribute ‘email‘

五:property属性

property() 函数的作用是在新式类中返回属性值。

In [375]: class duck():
     ...:     def __init__(self,input_name):
     ...:         self.hidden_name=input_name
#定义get和set方法
     ...:     def get_name(self):
     ...:         print("inside the getter")
     ...:         return self.hidden_name
     ...:     def set_name(self,input_name):
     ...:         print("inside the setter")
     ...:         self.hidden_name=input_name
     ...:     name=property(get_name,set_name)
     ...:
#方式1
In [376]: fowl=duck("caicai")
In [377]: fowl.name
inside the getter
Out[377]: ‘caicai‘
In [378]: fowl.get_name()
inside the getter
Out[378]: ‘caicai‘
#方式二
In [379]: fowl.name="cmf"
inside the setter
In [380]: fowl.name
inside the getter
Out[380]: ‘cmf‘
#方式三
In [382]: fowl.set_name("caiminfang")
inside the setter
In [383]: fowl.name
inside the getter
Out[383]: ‘caiminfang‘

实例

In [2]: class Duck():
   ...:     def __init__(self,input_name):
   ...:         self.hidden_name=input_name
   ...:     @property
   ...:     def name(self):
   ...:         print("insede the getter")
   ...:         return self.hidden_name
   ...:     @name.setter
   ...:     def name(self,input_name):
   ...:         print("inside the setter")
   ...:         self.hidden_name=input_name
   ...:
In [3]: ff=Duck("huahua")
In [4]: ff.name
insede the getter
Out[4]: ‘huahua‘
In [5]: ff.name="cmf"
inside the setter
In [6]: ff.name
insede the getter
Out[6]: ‘cmf‘

property底层代码

In [7]: property?
Init signature: property(self, /, *args, **kwargs)
Docstring:
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget is a function to be used for getting an attribute value, and likewise
fset is a function for setting, and fdel a function for del‘ing, an
attribute.  Typical use is to define a managed attribute x:

class C(object):
    def getx(self): return self._x
    def setx(self, value): self._x = value
    def delx(self): del self._x
    x = property(getx, setx, delx, "I‘m the ‘x‘ property.")

Decorators make defining new properties or modifying existing ones easy:

class C(object):
    @property
    def x(self):
        "I am the ‘x‘ property."
        return self._x
    @x.setter
    def x(self, value):
        self._x = value
    @x.deleter
    def x(self):
        del self._x
Type:           type

六:类方法

也叫类型方法,用@classmethod做标记的方法.假设其有n个必传参数,如果是类调用,则需要传n-1个参数,第一个参数同样是内定的类型本身。如果是实例调用,则需要传n个参数。类方法要让类型能调用,当然也需要至少一个参数.

类方法,第一个参数必须要默认传类,一般习惯用cls。

In [24]: class a():
    ...:     count=0
    ...:     def __init__(self):
    ...:         a.count+=1
    ...:         print(a.count)
    ...:     def ex(self):
    ...:         print("i am a")
    ...:     @classmethod
    ...:     def kids(cls):
    ...:         print("a has",cls.count)
    ...:         

In [25]: aa=a()
1

In [26]: bb=a()
2

In [27]: cc=a()
3

In [28]: a.kids()
a has 3

七:静态方法

@staticmethod标记的方法。类和实例都可以调用。无内定的参数问题,方法有多少参数就必须传递多少参数。

静态方法,参数没有要求。下面例子为空

In [29]: class a():
    ...:     @staticmethod
    ...:     def name():
    ...:         print("name")
    ...:         

In [30]: a.name()
name

八:魔术方法

除了__init__()外,还有最常用的__str__(),他用于定义如何打印信息。print()方法,str()方法以及一些字符串格式化的相关方法都会用到__str__(),交互式解释器则用__repr__()方法输出变了。

如果你的类既没有定义__str__()也没有定义___repr__(),python会输出类似下面的默认字符串:

In [37]: class word():
    ...:     def __init__(self,text):
    ...:         self.text=text
    ...:     def equals(self,word2):
    ...:         return self.text.lower()==word2.text.lower()
    ...:     

In [38]: first=word(‘ha‘)

In [39]: second=word("qwe")

In [40]: third=word(‘HA‘)

In [41]: first.equals(third)
Out[41]: True

In [42]: first.equals(second)
Out[42]: False

In [43]: first==second
Out[43]: False
#由于该类中没有__str__(),__repr__()方法,所以出现了下面的字符串
In [44]: first
Out[44]: <__main__.word at 0x7f841efaaeb8>

我们将__str__()和__repr__()方法都加到word类中,让输出的信息更变好看些

In [45]: class word():
    ...:     def __init__(self,text):
    ...:         self.text=text
    ...:     def equals(self,word2):
    ...:         return self.text.lower()==word2.text.lower()
    ...:     def __str__(self):
    ...:         return self.text
    ...:     def __repr__(self):
    ...:         return ‘word(‘+self.text+‘)‘
    ...:     

In [46]: first=word(‘ha‘)

In [47]: first
Out[47]: word(ha)

In [48]: print(first)
ha

九组合(compositoon)和聚合(aggregation)

In [62]: class hair():
    ...:     def __init__(self,color):
    ...:         self.color=color
    ...:
#定义头发的颜色
In [63]: class mouth():
    ...:     def __init__(self,size):
    ...:         self.size=size
    ...:
#定义嘴巴的函数
In [64]: class Person():
    ...:     def __init__(self,hair,mouth):
    ...:         self.hair=hair
    ...:         self.mouth=mouth
    ...:     def about(self):
#print(Hair.color,Mouth.size)该处的Hair必须写hair的实例化对象
    ...:         print(Hair.color,Mouth.size)
    ...:
In [65]: Hair=hair("yellow")
In [66]: Mouth=mouth("small")
In [67]: person=Person(Hair,Mouth)
In [68]: person.about()
yellow small
时间: 2024-10-08 22:37:01

【九】面向对象的相关文章

&lt;九&gt;面向对象分析之UML核心元素之设计类,类,属性,方法,可见性

设计类 --->设计类是系统实施中一个或多个对象的抽象.        --->设计类已经直接映射到实现代码了,因此设计类依赖于实施语言.另一方面,设计类来源于前期的系统分析,在统一过程中,类不是品空想像出来的.他们可以一一映射到前期系统分析的成果上.从这个观点出发,分析类的重要性就能够体现出来.分析类为设计类中多需要的界面,逻辑和数据提供了非常好的抽象基础,设计类可以非常容易和自然地从分析类中演化出来. 类        --->类对对象进行定义,而对象又实现(或成为实施)用例.类的来

九:面向对象

1.OOP python没有面向对象完全可以用函数解决所有的编程问题,有了OOP让变成更加有条理. 但是java就是完全的面向对象,所有都封装在类里面,单独方法不能出现在类之外.python天生多态,java里面的多态多用接口和父类 面相函数编程:多数情况下数据是函数内部传入函数内部,得到函数执行结果,完成需求 面向对象编程:将数据初始化的时候封装到对象里面,方法用数据直接用对象里面的. 面向函数数据和逻辑是分离的,面向对象的数据和函数是封装在一个对象里面常驻内存,方便后续重复使用. 从IDE角

(转)面向对象编程初步

1 class Hand: 2 pass 3 class Foot: 4 pass 5 class Trunk: 6 pass 7 class Head: 8 pass 9 10 class Person: 11 def __init__(self,id_num,name,hand,foot,trunk,head): 12 self.id_num=id_num 13 self.name=name 14 self.hand=Hand() 15 self.foot=Foot() 16 self.tr

Python 面向对象和实例属性

一.三大编程范式 编程范式即编程的方法论,标识一种编程风格. 我们学习完Python语法后,就可以写python代码了,然后每个人写代码的风格不同,这些不同的风格就代表了不同的流派. 如果把python的基本语法比作无数的基本功,那么不同的编程风格就好比不同的武林门派. 虽然大家风格不同,但是都可以完成你的编程需求,Python是一门面向对象编程语言,但是到目前为止,你从未接触面向对象编程,然而你已经可以解决很多问题了,在Python中并没有人强制你使用哪一种固定的风格. 根本就没有什么门派是天

第十九章 面向对象的工具

学习要点:1.OOP 的魔术方法2.类函数和对象函数3.OOP 的反射API PHP通过类和方法等语言结构支持面向对象编程.同时也通过对象相关的函数和内置类为面向对象提供广泛支持. 一.OOP的魔术方法 PHP引入了__autoload()内置方法来自动包含类文件.__autoload()应该被写成单个参数的方法.当PHP引擎遇到试图实例化未知类的操作时,会调用__autoload()方法,并将类名当作字符串参数传递给它. function __autoload($_className) { r

零散知识点(面向对象七大设计原则,jdbc--BaseDao,jsp九大内置对象。四个作用域)

面向对象七大设计原则: 1.开闭原则(OCP:Open-Closed Principle)2.里氏替换原则(LSP:Liskov Substitution Principle) 3.单一职责原则(SRP:Single responsibility principle)4.接口隔离原则(ISP:Interface Segregation Principle)5.依赖倒置原则(DIP:Dependence Inversion Principle)6.迪米特法则(LOD:Law of Demeter)

sdut 面向对象程序设计上机练习九(对象指针)

面向对象程序设计上机练习九(对象指针) Time Limit: 1000MS Memory limit: 65536K 题目描述 建立对象数组,内放5个学生数据(学号是字符串类型.成绩是整型),设立max函数,用指向对象的指针作函数参数,在max函数中找出5个学生中成绩最高者,并输出其学号和成绩. 输入 输入5个学生数据. 输出 输出5个学生中成绩最高者的学号和成绩. 示例输入 01 89 02 78 03 56 04 92 05 76 示例输出 04 92 来源 #include <iostr

java面向对象编程(九)--final

1.final概念 final可以修饰变量或者方法.在某些情况下,程序员可能有以下需求: a.当不希望父类的某个方法被子类覆盖(override)时,可以用final关键字修饰. b.当不希望类的某个变量的值被修改,可以用final修饰.如果一个变量是final,则必须赋初值,否则编译出错. c.当不希望类被继承时,可以用final修饰. //final方法的使用[Demo128.java] public class Demo128 { public static void main(Strin

20182332 《数据结构与面向对象程序设计》实验九报告

20182332 <数据结构与面向对象程序设计>实验九报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 盛国榕 学号:20182332 实验教师:王志强 实验日期:2019年12月3日 必修/选修: 必修 1.实验内容: 完成图的综合实践 (1)初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数.边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分) (2)图的遍历:完成有向图

20182330 2019-2020-1 《数据结构与面向对象程序设计》实验九报告

20182330 2019-2020-1 <数据结构与面向对象程序设计>实验九报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 魏冰妍 学号:20182330 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 完成图的综合实践 (1)初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数.边个数,建议先在草稿纸上画出图,然后再输入顶点和边数) (2)图的遍