面向对象day1

一、什么是面向对象

之前我们学习过面向过程和函数式编程,在讲函数的时候有说过之所以有函数式编程是因为面向过程编程是根据业务逻辑从上到下垒代码,会出现大量代码的重用和臃肿,so,函数式编程将同一功能的代码封装起来,方便日后调用,避免重复编写。而随着业务逻辑的需求,函数式编程一样回出现面向过程同样的问题,于是就有了面向对象编程,以实现对函数进行分类和封装,减少代码量。

面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)

二、创建类和对象

面向对象编程其实就是对类和对象的使用。类就是一个模板,模板里可以包含多个函数,函数里实现一些功能;对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。

class Too:#创建类名为Too的类
#创建类中的函数
    def Air(self):#self是特殊参数,必填
        pass
obj=Too()#根据类Too创建对象obj
class Foo:
    def Bar(self):
        print(‘bar‘)
    def Hello(self,name):
        print(‘I am %s‘%name)
#根据类Foo创建对象obj
obj=Foo()
obj.Bar()#执行Bar方法
obj.Hello(‘tina‘)#执行Hello方法

三、面向对象的三大特性

1、封装

封装,就是讲相同的内容封装到某个地方,方便日后再去调用被封装在某处的内容。so,在使用面向对象的封装时,需要:

  • 将内容封装到某处
  • 从某处调用被封装的内容
#在对象中封装数据的方法一(不推荐):
class Oldboy:
    def fetch(self,backend):
        print(backend,self)
        return 1

obj1=Oldboy()#创建对象,实例
#在对象中封装数据
obj1.backend=‘www.xxxxx‘
#执行类中的方法
a=obj1.fetch(‘www‘)
print(a)

#方法二(推荐):
class Foo:
    def __init__(self,name,age):#称为构造方法,根据类创建对象时自动执行
        self.name=name
        slef.age=age
#根据类Foo创建对象
#自动执行Foo类的__init__方法
obj1=Foo(‘tina‘,18)
obj2=Foo(‘feifei‘,22)

self是一个形式参数,当执行obj1=Foo(‘tina‘,18)时,self等于obj1,当执行obj2=Foo(‘feifei‘,22),self等于obj2

调用被封装的内容时,又分为两组情况:

(1)、通过对象直接调用:(对象.属性名)

class Foo:
    def __init__(self,name,age):
        self.name=name
        slef.age=age

obj1=Foo(‘tina‘,18)
print(obj1.name)#直接调用obj1对象的name属性
print(obj1.age)#直接调用obj1对象的age属性
obj2=Foo(‘feifei‘,22)
print(obj2.name)#直接调用obj2对象的name属性
print(obj2.age)#直接调用obj2对象的age属性

(2)、通过self间接调用:(执行类中的方法时,通过self间接调用被封装的内容)

class Foo:

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

    def detail(self):
        print(self.name)
        print(self.age)

obj1 = Foo(‘tina‘, 18)
obj1.detail()  # Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 tina ;self.age 是 18

obj2 = Foo(‘feifei‘, 22)
obj2.detail()  # Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是feifei ; self.age 是 22

综上,对于面向对象的封装来说,实质就是使用构造方法将内容封装到对象中,然后通过对象直接或self间接获取被封装的内容。

class Person:
    def __init__(self,name,age,weight):
        self.Name=name
        self.Age=age
        self.Weight=weight
    def chi(self):
        self.Weight+=2
    def excese(self):
        self.Weight-=1

o1=Person(‘tina‘,18,99)
o1.excese()
o1.chi()
print(o1.Weight)

练习一

class Lianxi:
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
    def sp(self):
        print(‘%s,%s岁,%s,sleeping‘%(self.name,self.age,self.gender))
        return 1
    def rn(self):
        print(‘%s,%s岁,%s,running‘%(self.name,self.age,self.gender))
    def tk(self):
        print(‘%s,%s岁,%s,talking‘%(self.name,self.age,self.gender))
obj1=Lianxi(‘tina‘,11,‘girl‘)
obj1.sp()
obj1.rn()
obj1.tk()
obj2=Lianxi(‘feifei‘,18,‘female‘)
obj2.sp()
obj2.rn()
obj2.tk()

练习二

class Person:
    def __init__(self,name,gender,age,fighting):
        self.name=name
        self.gender=gender
        self.age=age
        self.fight=fighting
    def grassland(self):
        self.fight -=200
    def practice(self):
        self.fight +=100
    def scuffle(self):
        self.fight -= 500
    def detail(self):
        t="姓名:%s ; 性别:%s ; 年龄:%s ; 战斗力:%s"  % (self.name, self.gender, self.age, self.fight)
        print(t)
obj1=Person(‘谢耳朵‘,‘men‘,12,10000)
obj2=Person(‘莱纳德‘,‘male‘,11,2000)
obj3=Person(‘珍妮‘,‘girl‘,13,7000)
obj1.grassland()
obj2.scuffle()
obj3.practice()
obj1.detail()
obj2.detail()
obj3.detail()
###########执行结果如下:############
姓名:谢耳朵 ; 性别:men ; 年龄:12 ; 战斗力:9800
姓名:莱纳德 ; 性别:male ; 年龄:11 ; 战斗力:1500
姓名:珍妮 ; 性别:girl ; 年龄:13 ; 战斗力:7100

练习三

2、继承

面向对象中的继承跟生活中的继承一个道理,即:子可以继承父的内容。

python中继承跟其他语言不同的地方在于:Java或C++中面向对象的继承只能继承一个,即只能继承父类;而python中面向对象的继承则能继承多个,即可以继承父亲的又可以继承叔叔的,寻找方法的顺序则是从左到右进行溯源。

class Animals:
    def chi(self):
        print(self.name+‘吃吃吃‘)
    def he(self):
        print(self.name+‘喝喝喝‘)
class Dog(Animals):#类名后面有括号就是继承,没括号就是基类
    def __init__(self,name):
        self.name=name
    def jiao(self):
        print(self.name+‘汪汪汪‘)
obj1=Dog(‘xx‘)
obj1.jiao()
obj1.chi()
obj1.he()

从上面的例子中,我们将基类Animals的方法继承给Dog,然后创建一个名字叫“xx”的狗对象,于是,叫“xx”的狗就可以直接调用基类的方法(属性)了,减少了很多共同特征的重复编写。

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()

猫狗继承动物属性的案例

#!/usr/bin/env python
#-*- coding:utf-8 -*-

class Game_pmodel(object):
    def __init__(self,name,profession,attack=0,blood=0,speed=0): #构造函数,名字和职业等信息
        self.name = name   #定义普通字段
        self.profession = profession #定义普通字段
        self.attack = attack
        self.blood = blood
        self.speed = speed

    def supershuai(self):
        self.blood = self.blood + 1000
        self.attack = self.attack + 1000
        self.speed = self.speed + 1000
        print "\033[32;1m呼叫及时当前血量:%s 当前攻击为:%s,当前速度为:%s" % (self.blood,self.attack,self.speed)
    def add_attack(self):
        self.attack = self.attack +300
        print "\033[32;1m您当前的攻击力为%s\033[0m" % self.attack
    def aspirine(self):
        self.blood = self.blood + 300
        print "\033[32;1m您当前的血量为%s\033[0m" % self.blood
    def detail(self):
        """注释:当前对象的详细情况"""
        temp = "角色:%s ; 职业:%s ; 战斗力:%s ; 血量:%s ; 速度:%s"  % (self.name, self.profession, self.attack, self.blood,self.speed)
        print temp

class Warrior(Game_pmodel):
    def weapon(self):
        self.attack = self.attack + 1000
        print "\033[32;1m拿起武器攻击力+1000,您现在的攻击力是:%s \033[0m"  % self.attack

高大上的继承案例

综上,对于面向对象的继承来说,其实就是将多个共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

 *注:子类和父类,又叫派生类和基类。

多继承的优先级关系:当继承多个类发生冲突时,优先级是:先自己,然后先左再右

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找

经典类的格式:class Classics:

#经典类多继承的栗子:
class D:                  #经典类
    def bar1(self):
        print("D.bar1")

class C(D):
    def bar1(self):
        print("C.bar1")

class B(D):
    # def bar1(self):
    #     print "B.bar1"
    pass                  #pass 代表什么也不做

class A(B,C):
    # def bar1(self):
    #     print("A.bar1")
    pass                  #pass 代表什么也不做

op = A()                  #实例化对象op
op.bar1()

#######执行结果如下#######
D.bar1

思考一个问题:为什么访问到了D.bar1?

当我们实例化op,并且调用bar1方法时,由于在类中有多个bar1方法,因此对于经典类,它自己有一个查找顺序,A ---> B --> D --> C
具体描述:
首先找A,如果A中没有,则找B,如果B中没有,再找D,如果D中也没有,最后找C,都没有找到,则报错;这种访问方式叫做深度优先

对于上面这个例子,由于找A 和 B 时都没有找到,则找到了D,因此打印了D.bar1,

分析结果——深度优先

新式类的格式:class New(object):

对于新式类,要在类名后的括号中写上object,object 也是一个类,class New(object),相当于继承了object 类, 则这个类称为新式类,新式类是我们今后推荐的写法。

#新式类多继承的栗子:class Tina(object):    #新式类
    def f1(self):
        print(‘Tina‘)
class A(Tina):
    def f(self):
        print(‘A‘)
class B(Tina):
    def f(self):
        print(‘B‘)
class C(A):
    def f(self):
        print(‘C‘)
class D(B):
    def f(self):
        print(‘D‘)
class E(C,D):
    def f(self):
        print(‘E‘)
obj=E()
obj.f1()

###########执行结果如下#########
Tina

同样思考一个问题:为什么访问到了Tina?代码的执行流程是怎样的?

# 首先去C类中查找,如果C类中没有,则继续去A类中找,如果A类中没有,则继续去D类中找,如果D类中么有,则继续去B类中找,如果B中没有,去T中去找,还是未找到,则报错
# 所以,查找顺序:C --> A --> D --> B --> T
# 在上述查找方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了

分析结果——广度优先

3、多态

时间: 2024-10-14 04:19:54

面向对象day1的相关文章

Python3 面向对象 高级编程

正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.  class Student(object): pass 然后,尝试给实例绑定一个属性: >>> s = Student() >>> s.name = 'Michael' # 动态给实例绑定一个属性 还可以尝试给实例绑定一个方法: >>> def set_age(self, age): # 定义一个函数作为实例方法 ...

python 之面向对象高级编程

数据封装.继承和多态只是面向对象程序设计中最基础的3个概念.在Python中,面向对象还有很多高级特性,允许我们写出非常强大的功能. 我们会讨论多重继承.定制类.元类等概念. 使用__slots__ 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: class Student(object): pass 然后,尝试给实例绑定一个属性: >>> s = Student() >>&

python 面向对象编程(一)

一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class className: block 注意类名后面有个冒号,在block块里面就可以定义属性和方法了.当一个类定义完之后,就产生了一个类对象.类对象支持两种操作:引用和实例化.引用操作是通过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象的实例,称作实例对象.比如定义了一个people类: cl

python基础之面向对象高级编程

面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个"函数"供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数 面向对象三大特性:封装.继承和多态 本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有

Python学习笔记——面向对象编程

接下来学习面向对象编程,基础的就不记录了,只记录一些Python特有的或者高级的特性. http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318645694388f1f10473d7f416e9291616be8367ab5000 1. 类的定义 定义类使用class关键字,后面紧跟类名(首字母大写),接着是从哪个类继承下来的(所有类最终会继承object). 通过类名加参

python学习 面向对象封装

from collectoins import namedtuplePoint=namedtuple('point',['x','y'])t1=Point(1,2)print(t1.x)print(t1.y)没有方法的类属性不会发生变化    定义简单 不能改变面向对象封装私有属性!!!私有方法!!!用装饰器描述的几个方法@property !!!@classmethod!!@staticmethod! 封装:class Teacher:     def __init__(self,name,p

python—面向对象的封装

封装 私有属性 class Teacher: __identifier = 'Teacher' #私有静态属性 def __init__(self,name,pwd) self.name = name self.__pwd = pwd #私有属性 内部使用,外部不能使用 def pwd(self): print(self.__pwd) alex = Teacher('alex','3714') alex.pwd() class Teacher: __identifier = 'Teacher'

python学习_day26_面向对象之封装

1.私有属性 (1)动态属性 在python中用双下划线开头的方式将属性隐藏起来.类中所有双下划线开头的名称,如__x都会自动变形成:_类名__x的形式.这种自动变形的特点是: a.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果.b.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的.c.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆

python面向对象知识点疏理

面向对象技术简介 类: 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例.class 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外.类变量通常不作为实例变量使用. 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据. 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写. 实例变量:定义在方法中的变量,只作用于当前实例的类. 继承:即一个派生类(de