python 面向对象编程

 一:面向对象编程      

 初学编程的方法通常由顺序结构开始。这是步骤式的过程性编程,过程式编程方法下的制成品,是一个“大胖子”,为什么呢?假设拆开这个制成品,里面是无数纠缠不清的程序和数据(变量等),数据是给各程序共享的。即任何程序都可以读取或修改它,一个程序接着另一个程序来执行。假设要修改这个制成品,就有一种触一发牵动全身的感觉,例如改了这个程序,可能会影响其他的程序。

 OOP(Object-Oriented Programming)面向对象编程 

面向对象程序设计的诞生为开发策略带来的极大的改变,使编程的注意力重新从应用程序的逻辑回到其数据上来。换句话说,OOP将焦点从过程式编程转向最终建模的真实实体。这使得应用程序更接近我们周围的现实世界。

OOP达到了软件工程的三个目标:重用性、灵活性和扩展性。

采用面向对象方法可以使系统各部分各司其职、各尽所能; 使其编程的代码更简洁、更易于维护,并且具有更强的可重用性。

二:类和对象

类 (class)

类就像是一个模板或设计图,它定义了某个概念或真实事物的性质和行为。

它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分。

在OOP术语中,实体的性质和行为的具体定义称为类。

 对象 (object)

通过类创建出来的实体称为对象。

对象是系统中用来描述客观事物的一个实体。它是构成系统的一个基本单位,数据与代码都被捆绑在一个实体中。一个对象由一组属性和对这组属性进行操作的一组行为组成。

        从更抽象的角度来说,对象是问题域或实现域中某些事物的一个抽象,它反映该事物在系统中需要保存的信息和发挥的作用;它是一组属性和有权对这些属性进行操作的一组行为的封装体。客观世界是由对象和对象之间的联系组成的。   

三:类和对象关系

类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,而对对象的抽象就是类.类描述了一组有相同特性(属性)和相同行为(方法)的对象。

python 面向对象编程_第1张图片

四:从对象抽象出类

python 面向对象编程_第2张图片

五:类

python 面向对象编程_第3张图片

六:Python是面向对象的语言

关键字class定义自定义的数据类型

class Foo:
     
    def Bar(self):
        print 'Bar'
 
    def Hello(self, name):
        print 'i am %s' %name

七:方法与属性

类将现实世界中的概念模拟到计算机程序中

class  类名 :

       #定义属性部分

       def __init__(self, 初始值1,初始值1, ….):
         self.属性1 =初始值1

  self.属性2 =初始值2
         self.属性值n = 初始值n

        #定义方法部分

        方法1:

        方法2:

        …

        方法m:

八:定义类

定义一个类的步骤 :1、定义类名   2、编写类的方法

class Penguin:    
  def __init__(self, name, month, attack):        
    self.name = name        
    self.month = month        
    self.attack = attack    


  def eat(self):        
    self.name = '小星星'        
    print('我吃鱼呢')    


  def showMe(self):        
    print('我的名字是%s,我的攻击性是%d' % (self.name, self.attack))

九: 对象的实例化

对象实例化:将类加载到内存中  

对象名 = 类名()

class Penguin:    
  def __init__(self, name, month, attack):        
    self.name = name        
    self.month = month        
    self.attack = attack    
  def eat(self):        
    self.name = '小星星'        
    print('我吃鱼呢')    
  def showMe(self):        
    print('我的名字是%s,我的攻击性是%d' % (self.name, self.attack))
small = Penguin('xixi', '5', 100)

十:类和对象的区别

类是python的核心和本质。它是python语言的基础,因为类定义了对象的本质。

类定义了一种新的数据类型,可以用新类型来创建该类型的对象。

类(class)是对象(object)的模板,而对象(object)是类的一个实例(instance)。

十一:方法

方法是个“黑匣子”,完成某个特定的应用程序功能,并返回结果

方法调用:执行方法中包含的语句          

方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;

类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;

静态方法:由类调用;无默认参数;

十二:方法定义及调用

class Foo:

    def __init__(self, name):
        self.name = name
    def ord_func(self):
        """ 定义普通方法,至少有一个self参数 """
        # print self.name
        print '普通方法‘
    @classmethod
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print '类方法'
    @staticmethod
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print '静态方法'
# 调用普通方法
f = Foo()
f.ord_func()

# 调用类方法
Foo.class_func()

# 调用静态方法
Foo.static_func()

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

不同点:方法调用者不同、调用方法时自动传入的参数不同。

十三:属性的基本使用

属性其实是普通方法的变种

属性存在意义是:

    访问属性时可以制造出和访问字段完全相同的假象

    属性内部进行一系列的逻辑计算,最终将计算结果返回

语法

    定义时,在普通方法的基础上添加 @property 装饰器;

    定义时,属性仅有一个self参数

    调用时,无需括号
           方法:foo_obj.func()
           属性:foo_obj.prop

class Foo:

    def func(self):
        pass

    # 定义属性
    @property
    def prop(self):
        pass

foo_obj = Foo()

foo_obj.func()
foo_obj.prop   #调用属性

十四:属性的定义

class Goods:

    @property
    def price(self):
        print '@property'

    @price.setter
    def price(self, value):
        print '@price.setter'

    @price.deleter
    def price(self):
        print '@price.deleter'
#调用
obj = Goods()

obj.price          # 自动执行 @property 修饰的 price 方法,并获取方法的返回值

obj.price = 123    # 自动执行 @price.setter 修饰的 price 方法,并将  123 赋值给方法的参数

del obj.price      # 自动执行 @price.deleter 修饰的 price 方法

属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

class Goods(object):
    def __init__(self):
        # 原价
        self.original_price = 100
        # 折扣
        self.discount = 0.8
    @property
    def price(self):
        # 实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price
    @price.setter
    def price(self, value):
        self.original_price = value
    @price.deltter
    def price(self, value):
        del self.original_price
obj = Goods()
obj.price         # 获取商品价格
obj.price = 200   # 修改商品原价
del obj.price     # 删除商品原价

属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

十五:类成员修饰符

每一个类的成员而言都有两种形式

    公有成员,在任何地方都能访问

    私有成员,只有在类的内部才能方法

私有成员和公有成员的定义不同

    私有成员命名时,前两个字符是下划线

python 面向对象编程_第4张图片

 私有成员和公有成员的访问限制不同

    公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问

    私有普通字段:仅类内部可以访问;

class C:    
    def __init__(self):
        self.foo = "公有字段"

    def func(self):
        print(self.foo)  # 类内部访问

class D(C):  
    def show(self):
        print(self.foo) # 派生类中访问
obj = C()
obj.foo     # 通过对象访问
obj.func()  # 类内部访问
obj_son = D();
obj_son.show()  # 派生类中访问
class C:
    def __init__(self):
        self.__foo = "私有字段"

    def func(self):
        print(self.foo)  # 类内部访问

class D(C):    
    def show(self):
        print(self.foo) # 派生类中访问
obj = C()
obj.__foo     # 通过对象访问    ==> 错误
obj.func()  # 类内部访问        ==> 正确
obj_son = D();
obj_son.show()  # 派生类中访问  ==> 错误

 私有成员和公有成员的访问限制不同

    公有静态字段:类可以访问;类内部可以访问;派生类中可以访问

    私有静态字段:仅类内部可以访问;

class C:
    name = "公有静态字段"
    def func(self):
        print C.name

class D(C):
    def show(self):
        print C.name

C.name         # 类访问

obj = C()
obj.func()     # 类内部可以访问

obj_son = D()
obj_son.show() # 派生类中可以访问
class C:
    __name = “私有静态字段"
    def func(self):
        print C.__name

class D(C):
    def show(self):
        print C.__name

C.__name       # 类访问            ==> 错误

obj = C()
obj.func()     # 类内部可以访问     ==> 正确

obj_son = D()
obj_son.show() # 派生类中可以访问   ==> 错误

十六:面向对象三大特征

封装 继承 多态

十七:封装

封装就是把对象的属性和行为结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节

信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系。

封装的原则在软件上的反映是:要求使对象以外的部分不能随意存取对象的内部数据(属性),从而有效的避免了外部错误对它的“交叉感染”,使软件错误能够局部化,大大减少查错和排错的难度。

类的封装性带来的优点:隐藏类的实现细节,让使用者只能通过事先定义好的方法来访问数据,可以方便的加入逻辑控制,进行数据检查,限制对属性的不合理操作。便于修改增强代码的可维护性。

封装的实现:

1、在方法中,加入对属性的限制

2、在方法中,对输出的内容进行封装

Class employee :

	def __init__(self, name):
	    self.name = name
	def get_age(self):
	    return $self.age
	def set_age(age):
      if(age < 0 || age > 130):
			  return
		 self.age = age

十八:继承

是指可以让某个类型的对象获得另一个类型的对象的属性的方法。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。

生活中,继承的例子随处可见 

python 面向对象编程_第5张图片

python 面向对象编程_第6张图片

为什么继承?

开发动物类,其中动物分为猫以及狗,各自的要求如下:

属性:姓名、id

方法:喵喵叫、吃、喝、拉、撒

属性:姓名、id

方法:汪汪叫、吃、喝、拉、撒

python 面向对象编程_第7张图片

python 面向对象编程_第8张图片

python 面向对象编程_第9张图片

继承代码示例:

class Animal:

    def eat(self):
        print("%s 吃 " % self.name)

    def drink(self):
        print("%s 喝 " % self.name)

    def shit(self):
        print("%s 拉 " % self.name)

    def pee(self):
        print("%s 撒 " % self.name)
class Cat(Animal):
    def __init__(self, name):
        self.name = name
        self.breed = '猫'
    def cry(self):
        print('喵喵叫')
class Dog(Animal):
    def __init__(self, name):
        self.name = name
        self.breed = ‘狗'
    def cry(self):
        print(‘汪汪叫')
c1 = Cat('小白家的小黑猫')
c1.eat()

c2 = Cat('小黑的小白猫')
c2.drink()

d1 = Dog('胖子家的小瘦狗')
d1.eat()

十九:多继承

Python同样有限的支持多继承形式。多继承的类定义形式如下: 

python 面向对象编程_第10张图片

python 面向对象编程_第11张图片

python 面向对象编程_第12张图片

二十:方法重写

如果父类方法的功能不能满足需求,

可以在子类重写父类的方法,实例如下:

python 面向对象编程_第13张图片

python 面向对象编程_第14张图片

二十一:多态

1. 对象的多态性是指在父类中定义的属性或行为被子类继承之后,可以具有不同的数据类型或表现出不同的行为。通过继承过程中的方法重写就可以实现多态

2. 允许不同类的对象对同一消息作出响应。比如同样的加法,把两个时间加在一起和把两个整数加在一起肯定完全不同。

多态

    不同的子类对象 调用相同的 父类方法,产生不同的执行结果。

优点

    多态可以 增加代码的灵活度

    以 继承 和 重写父类方法 为前提

    是调用方法的技巧,不会影响到类的内部设计

类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法     

class Person:
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
    def whoAmI(self):
        return 'I am a Person, my name is %s' % self.name
class Teacher(Person):
    def __init__(self, name, gender, course):
        super(Teacher, self).__init__(name, gender)
        self.course = course
    def whoAmI(self):
        return 'I am a Teacher, my name is %s' % self.name
class Student(Person):
    def __init__(self, name, gender, score):
        super(Student, self).__init__(name, gender)
        self.score = score
    def whoAmI(self):
        return 'I am a Student, my name is %s' % self.name

 在一个函数中,如果我们接收一个变量 x,则无论该 x 是
Person、Student还是 Teacher,都可以正确打印出结果:

def who_am_i(x):
    print x.whoAmI()

p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')
who_am_i(p)
who_am_i(s)
who_am_i(t)
I am a Person, my name is Tim
I am a Student, my name is Bob
I am a Teacher, my name is Alice

这种行为称为多态。也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。

二十二:模块、包

模块

模块实质上就是一个python文件。它是用来组织代码的,意思就是把python代码写到里面,文件名就是模块的名称,test.py test就是模块的名称

包,package本质就是一个文件夹,和文件夹不一样的是它有一个__init__.py文件。包是从逻辑上来组织模块的,也就是说它是用来存放模块的,如果想到如其他目录下的模块,那么这个目录必须是一个包才可以导入。

二十三:模块分类

标准模块、标准包

    python自带的这些模块,直接import就能用的

    import string,random,datetime,os,sys,json,hashlib

第三方模块

    别人写好的一些模块,要安装之后才可以用

    想实现某个功能,可以先去百度搜一下有没有第三方模块

自己写的python文件

二十四:安装第三方模块

直接在命令行窗口输入命令  pip install open-python

pip在python3.4以上的版本是自带的。但这种方式需要保证pycharm中的Project Interpreter路径是Python安装路径,否则即使窗口显示下载安装成功,依然不能成功import

因为命令行下载下来的第三方安装包存储在Python安装路径\python3\Lib\site-packages

而pycharm import时,是从pycharm->File->Settings->Project Interpreter->设置的路径下\python\Lib\site-packages去取第三方安装包

限制外网无法直接下载时,可以找别人下载好包然后手动安装

1)python官网https://pypi.python.org 搜索包名下载安装包whl

2)安装whl结尾的安装包
地址栏中直接输入cmd,pip install xxx.whl即可安装成功          

你可能感兴趣的:(python,开发语言,软件工程)