面向对象初识一

初识面向对象 

1、面向对象和面向过程

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

面向过程特点:

优点:把复杂的问题流程化,简单化,比较容易想,可扩展性弱,处理单一关系代码量小

 

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

面向对象特点:

优点:可扩展性强(可增加新的方法)

缺点:可控性差(无法预测结果)

处理复杂的关系,代码多,面向对象编程可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。

 

初识类和对象:

类:具有相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程

在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。

 

类:

def functionName(args):
     '函数文档字符串'
      函数体 
声明函数
'''
class 类名:
    '类的文档字符串'
    类体
'''

#我们创建一个类
class Data:
    pass
声明类
class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def walk(self):  #人都可以走路,也就是有一个走路方法,也叫动态属性
        print("person is walking...")

 

类有两种作用:属性引用和实例化

class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def walk(self):  #人都可以走路,也就是有一个走路方法
        print("person is walking...")


print(Person.role)  #查看人的role属性
print(Person.walk)  #引用人的走路方法,注意,这里不是在调用
属性引用
class Person:   #定义一个人类
    role = 'person'  #人的角色属性都是人
    def __init__(self,name):
        self.name = name  # 每一个角色都有自己的昵称;
        
    def walk(self):  #人都可以走路,也就是有一个走路方法
        print("person is walking...")


print(Person.role)  #查看人的role属性
print(Person.walk)  #引用人的走路方法,注意,这里不是在调用
实例化

实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

实例化的过程就是类——>对象的过程

语法:对象名 = 类名(参数)

查看属性&调用方法

print(alex.name)     #查看属性直接 对象名.属性名
print(Alex.attack())   #调用方法,对象名.方法名()

注  :self:在实例化时自动将对象/实例本身传给__init__的第一个参数

 

对象:

class Person:    # 类名 Person
    role = ''  # 类的静态变量 是所有的对象共享的一个属性
    def __init__(self,name,sex,aggr,hp):  #方法 动态属性  内置的双下方法
        self.name = name    # 对象属性 实例属性
        self.sex = sex
        self.aggr = aggr
        self.hp = hp
    def attack(self,dog):  # 自定义方法
        dog.hp -= self.aggr
        print('%s打了%s'%(self.name,dog.name))
        # dog.hp -= self.aggr

class Dog:
    def __init__(self,name,kind,aggr,hp):
        self.name = name   # 对象属性
        self.kind = kind
        self.aggr = aggr
        self.hp = hp
    def bite(self,person):
        person.hp -= self.aggr
        print('%s咬了%s'%(self.name,person.name))
        # person.hp -= self.aggr
hei = Dog('小黑','teddy',260,10000)  # 实例化: 先创造对象 再初始化
alex = Person('alex','female',1,250)  # 实例化
egon = Person('egon','male',2,500)  # 实例化
alex.attack(hei)   # Person.attack(alex,hei)
egon.attack(hei)   # Person.attack(alex,hei)
print(hei.hp)
hei.bite(alex)
print(alex.hp)
人狗大战

对象是关于类而实际存在的一个例子,即实例,

对象只有一种作用:属性引用

当然了,你也可以引用一个方法,因为方法也是一个属性,只不过是一个类似函数的属性,我们也管它叫动态属性。
引用动态属性并不是执行这个方法,要想调用方法和调用函数是一样的,都需要在后面加上括号,如Alex.attack

class 类名:
    def __init__(self,参数1,参数2):
        self.对象的属性1 = 参数1
        self.对象的属性2 = 参数2

    def 方法名(self):pass

    def 方法名2(self):pass

对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西
                  #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
                  #括号里传参数,参数不需要传self,其他与init中的形参一一对应
                  #结果返回一个对象
对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可
对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可
总结

 

2  、类命名空间与对象、实例的命名空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

  • 静态属性就是直接在类中定义的变量
  • 动态属性就是定义在类中的方法

其中类的静态属性是共享给所有对象的

>>>id(egg.role)
4341594072
>>>id(Person.role)
4341594072

而类的动态属性是绑定到所有对象的

 

创建一个对象就会创建一个对象的名称空间,存放对象的名字,称为对象的属性

      在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类(不会去全局变量中找)-..最后都找不到就抛出异常

 

3、面向对象的组合用法

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

 

圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用

 

from math import pi

class Circle:
    '''
    定义了一个圆形类;
    提供计算面积(area)和周长(perimeter)的方法
    '''
    def __init__(self,radius):
        self.radius = radius

    def area(self):
         return pi * self.radius * self.radius

    def perimeter(self):
        return 2 * pi *self.radius


circle =  Circle(10) #实例化一个圆
area1 = circle.area() #计算圆面积
per1 = circle.perimeter() #计算圆周长
print(area1,per1) #打印圆面积和周长
普通做法
from  math  import pi
class Ring:
    '''
    定义了一个圆环类
    提供圆环的面积和周长的方法
    '''
    def __init__(self,radius_outside,radius_inside):
        self.outsid_circle = Circle(radius_outside)
        self.inside_circle = Circle(radius_inside)

    def area(self):
        return self.outsid_circle.area() - self.inside_circle.area()

    def perimeter(self):
        return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()


ring = Ring(10,5) #实例化一个环形
print(ring.perimeter()) #计算环形的周长
print(ring.area()) #计算环形的面积
组合做法

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程

class BirthDate:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day

class Couse:
    def __init__(self,name,price,period):
        self.name=name
        self.price=price
        self.period=period

class Teacher:
    def __init__(self,name,gender,birth,course):
        self.name=name 
        self.gender=gender
        self.birth=birth
        self.course=course
    def teach(self): 
        print('teaching')

p1=Teacher('egon','male', 
            BirthDate('1995','1','27'), 
            Couse('python','28000','4 months')
           ) 

print(p1.birth.year,p1.birth.month,p1.birth.day) 

print(p1.course.name,p1.course.price,p1.course.period)
''' 
运行结果: 
27 
python 28000 4 months 
'''
View Code

人狗大战升级版:

class Weapon:
    def __init__(self,name,price,aggr,protect):
        self.name = name
        self.price = price
        self.aggr = aggr
        self.protect = protect

    def kill(self,dog):   # 技能
        print('使用%s的必杀技,打中%s'%(self.name,dog.name))
        dog.hp -= self.aggr
        print('%s的生命值减少%s,剩余%s'%(dog.name,self.aggr,dog.hp))

class Person:    # 类名 Person
    role = ''  # 类的静态变量 是所有的对象共享的一个属性
    def __init__(self,name,sex,aggr,hp):  #方法 动态属性  内置的双下方法
        self.name = name    # 对象属性 实例属性
        self.sex = sex
        self.aggr = aggr
        self.hp = hp
    def attack(self,dog):  # 自定义方法
        print('%s打了%s'%(self.name,dog.name))
        dog.hp -= self.aggr

class Dog:
    def __init__(self,name,kind,aggr,hp):
        self.name = name   # 对象属性
        self.kind = kind
        self.aggr = aggr
        self.hp = hp
    def bite(self,person):
        print('%s咬了%s'%(self.name,person.name))
        person.hp -= self.aggr

weapon = Weapon('屠龙宝刀',20000,999,0)
alex = Person('alex','female',1,250)
hei = Dog('小黑','teddy',260,10000)
alex.attack(hei)
print(hei.hp)
hei.bite(alex)
print(alex.hp)
ret = input('输入1可以充值复活 :')
if ret == '1':
    money = int(input('10000元复活一次,你要充值多少钱:'))
    if money>10000:
        alex.hp = 260
        alex.money = money - 10000
        print('复活成功,当前血量%s,当前账户余额%s'%(alex.hp,alex.money))
    ret = input('输入1购买武器')
    if ret == '1':
        if alex.money >= 20000:
            alex.money -= weapon.price
            alex.weap = weapon
            print('购买成功,当前余额%s,当前武器%s'%(alex.money,alex.weap.name))
alex.weap.kill(hei)  # alex使用武器打小黑
hei.bite(alex)  # 小黑怒不可遏咬alex
print(alex.hp)  # 最终查看alex的血量
人狗大战升级版

 

练习:

用面向对象的思想完成下列练习:

一、求圆形、正方形、长方形的周长和面积

# 计算圆面积和周长
from math import pi
class Circle:
    def __init__(self,R):
        self.R = R
    def area(self):
        print(pi*(self.R**2))
    def perimeter(self):
        print(2*self.R*pi)
c = Circle(4)
c.area()
c.perimeter()


# 计算正方形面积和周长
class Square:
    def __init__(self,s):
        self.s = s
    def area(self):
        return self.s**2
    def perimeter(self):
        return self.s*4
a = Square(5)
print(a.area())
print(a.perimeter())


# 计算长方形面积和周长
class Retangle:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def area(self):
        return self.a*self.b
    def perimeter(self):
        return 2*(self.a + self.b)
n = Retangle(3,4)
print(n.area())
print(n.perimeter())
View Code

二、人狗大战练习

# 人狗大战
class Person:
    def __init__(self,name,sex,aggr,hp):
        self.name = name
        self.sex = sex
        self.aggr = aggr
        self.hp = hp
    def attack(self,dog):
        print('%s打了%s,掉了%s的血'%(self.name,dog.name,self.aggr))
        dog.hp -= self.aggr
class Dog:
    def __init__(self,name,kind,aggr,hp):
        self.name = name
        self.kind = kind
        self.aggr = aggr
        self.hp = hp
    def bite(self,person):
        print('%s咬了%s,掉了%s的血'%(self.name,person.name,self.aggr))
        person.hp -= self.aggr

alex = Person('alex','female',200,500)
hei = Dog('hei','teddy',150,300)
hei.bite(alex)
alex.attack(hei)
print(hei.hp)
print(alex.hp)

>>>
hei咬了alex,掉了150的血
alex打了hei,掉了200的血
100
350
人狗大战

三、打印如下类型语句

# 小明,男,10岁,上山去砍柴
# 小明,男,10岁,开车去东北
# 小明,男,10岁,最爱大保健
# 老张,男,90岁,上山去砍柴
# 老张,男,90岁,开车去东北
# 老张,男,90岁,最爱大保健
# 老王,男,70岁,上山去砍柴
# 老王,男,70岁,开车去东北
# 老王,男,70岁,最爱大保健

class Person:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def drive(self):
        print('%s,%s,%s岁,开车去东北'%(self.name,self.sex,self.age))
    def climb(self):
        print('%s,%s,%s岁,上山去砍柴'%(self.name,self.sex,self.age))
    def hobby(self):
        print('%s,%s,%s岁,最爱大保健'%(self.name,self.sex,self.age))


ming = Person('小明', '',10)
ming.drive()
ming.climb()
ming.hobby()
zhang = Person('老张','',90)
zhang.drive()
zhang.climb()
zhang.hobby()
wang = Person('老王','',70)
wang.drive()
wang.climb()
wang.hobby()
View Code

 

posted @ 2018-03-05 20:47  GuoXY  阅读(142)  评论(0编辑  收藏  举报