面向对象的补充

面向对象的特性补充

1.类属性

#!usr/bin/env python  
#-*- coding:utf-8 _*-
'''
面向对象开发
1.设计类
2.使用类名创建对象
1.为对象分配内存空间
2.调用__init__为对象初始化
3.对象创建后,内存中的对象就有了一个对象实实在在的存在,------实例
我们把创建出来的对象又叫做实例

由类创建的对象:实例
创建对象的动作叫做 :实例化
对象的属性叫做:实例属性
对象调用的方法叫做:实例方法

创建的多个对象,多个对象每个在内存中有独立的内存空间
'''


# 类属性就是给类对象中定义的属性
# 通常用来记录与这个类相关的特征
# 类属性不会用来记录与对象有关的特征
# class Tools(object):
# # 使用赋值语句定义类属性,记录所有工具对象的数量
# count=0
# def __init__(self,name):
# self.name=name
#
# #让类属性的值+1
# Tools.count+=1
#
# # 1.创建工具对象
# tool1=Tools("FAX")
# tool2=Tools("LANGTOU")
# tool3=Tools("JIAZI")
# # 类名.类属性:来访问类属性
# print(Tools.count)
# # 使用对象名也可以访问类属性,但是不推荐使用

'''
类方法
与实例方法非常的类似
@classmethod
def 类方法名(cls):
pass
类方法的第一个参数是cls
通过类名调用类方法,调用方法时不需要传递cls参数

在方法的内部可以通过cls.来访问类的属性
也可以通过cls.调用其他的方法
'''
#
class Tools(object):
count=0
@classmethod
def show_tool_count(cls):
print("工具对象的数量%d"%cls.count)

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

Tools.count+=1
tool1=Tools("FUTOU")
tool2=Tools("BANZI")
# 直接使用类名.类方法名的方式
Tools.show_tool_count()

'''
不访问类属性,也不使用实例属性,可以定义一个静态方法
语法:
@staticmethod
def 静态方法名(不需要指定第一个参数)

pass

通过类名.方法名()来调用
'''
class Dog(object):
@staticmethod
def run():
#不访问类属性,也不访问实例属性
print("dog will run")

Dog.run()


多继承
'''
# 多继承
子类可以拥有多个父类,并且具有所有父类的属性和方法
多继承可以让子类同时拥有多个父类的属性和方法
语法;
class 子类名(父类名1,父类名2...)
pass

'''


'''
class A:
def test(self):
print("test 方法")

class B:
def demo(self):
print("demo 方法")

class C(A,B):
pass

c=C()
c.test()
c.demo()
'''

# 若父类之间存在同名的属性和方法,应该避免使用多继承
class A:
def test(self):
print("A---test 方法")

def demo(self):
print("A---demo 方法")

class B:
def test(self):
print("B---test 方法")

def demo(self):
print("B---demo 方法")

class C(B,A):
pass

c=C()
c.test()
c.demo()
print(C.__mro__)
'''
MRO:方法搜索顺序
__mro__这方法可以查看方法的执行顺序
'''

# 以object为基类的类都是基类 ,不以object为基类的类,是就是类
# 在今后运行的时候,如果没有父类,建议统一继承object类,方便在py2和py3中都能运行

多态
#!usr/bin/env python  
#-*- coding:utf-8 _*-
'''
多态
不同的子类对象,调用相同的父类方法,产生不同的结果

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

以继承和重写父类为前提

是调用方法的技巧,不会影响类的内部特性
'''

class Dog(object):
def __init__(self,name):
self.name=name

def game(self):
print("%s蹦蹦调药"%self.name)
class Xiaotianquan(Dog):
def game(self):
print("%s 飞到天生能去"%self.name)

class Person(object):
def __init__(self,name):
self.name=name

def game_with_dog(self,dog):
print("%s he %s 快乐的玩耍。。"%(self.name,dog.name))

# 让狗玩耍
dog.game()

# 1.创建一个狗对象
# wangcai=Dog()
wangcai=Xiaotianquan("飞天旺财")
# 2.创建一个小明对象
xiaoming=Person("小明")
xiaoming.game_with_dog(wangcai)


士兵突击小练习
class Gun:
def __init__(self,model):
# 1.枪的型号
self.model=model
# 2.子弹的数量
self.bullet_count=0

def add_bullet(self,count):
self.bullet_count+=count

def shoot(self):
# 1.判断子弹数量
if self.bullet_count<=0:
print("[%s]NO bullet..."%self.model)
return #没有子弹,下方的代码就不执行了
# 2.发射子弹
self.bullet_count-=1
# 提示发射信息
print("[%s]tututu [%d]"%(self.model,self.bullet_count))

class Soldier:
def __init__(self,name):
#1.新兵的姓名
self.name=name
# 2.枪-新兵没有枪
#在定义属性时,若不知道什么初始值,可以设置为none,none关键字表示什么都没有
self.gun=None#不要在外部设置属性,而是在方法内部将属性设置好
def fire(self):
#判断士兵是否有枪

# if self.gun==None:
if self.gun is None:
print("[%s] no gun"%self.name)
return#么有枪就直接返回

# 高喊口号
print("[%s] 高喊:冲啊"%self.name)

# 让自己的枪对象调用装子弹方法
self.gun.add_bullet(50)
#发射子弹
self.gun.shoot()

ak47=Gun("AK47")#创建了一个枪对象
# ak47.add_bullet(20)
# ak47.shoot()

# xusanfuo=Soldier("许三多")
# xusanfuo.gun=ak47#想要修改属性的值,就在属性外面直接赋值修改就行
# xusanfuo.fire()
# print(xusanfuo.gun)

'''
"身份运算符"
is :判断两个标识符是不是引用同一个对象
is not:判断判断两个标识符是不是引用不同的对象,即为内存地址是否相同
==这个运算符是判断值是否相等
'''
a=[1,2,3]
print(id(a))
b=[1,2,3]
print(id(b))
b.append(3)
print(id(b))


#!usr/bin/env python  
#-*- coding:utf-8 _*-
'''
所有步骤从头到尾逐步实现
根据开发的功能将某些代码封装成一个有一个函数
面向过程就是顺序的执行不同的函数
面向过程比较复杂,不适合复杂的项目
'''

'''
面向对象的侧重点是---------谁来做事情
根据职责确定不同的对象,在对象内部封装各自不同的方法
各个对象的方法很少会相互调用的
最后完成的代码,就是顺序的让不同的对象调用不同的方法

专门应对复杂项目,提供套路

'''

'''
类:
制造飞机使用的图纸
它可以指定飞机具有怎样的属性和特征
特征:属性------------用来描述类的特征的
行为:方法------------可以动的

类是一个模板,对象是根据模板对象创建出来的,应该先有类,再有对象
类只有一个,但是对象可以有很多个
不同的对象之间属性,可能各不相同
类中定义有什么样的对象和方法,对象就有什么样的属性和方法。
开发之前,要明确程序中要包含哪些类?
在给类起名字的时候要满足大驼峰命名法

类的三要素
类名:名词提炼法,分析整个业务,出现的名词,通常就是要找到的类
属性;对对象的描述
方法:对象具有的行为,通常定义成方法(动词


使用面向对象开发之前一定要先分析)
'''
# 面向对象的基本语法
# dir 内置函数:可以查看针对这个对象所有的属性和方法

def demo():
print("bububu")
demo()


# __方法名__这样的格式语法他是python提供的内置方法/ 属性,记不住的时候就用dir()查一下

'''
在python中定义类
class 类名:
def 方法1(self,参数列表):
pass
def 方法2(self,参数列表):
pass

方法定义的格式与之前学习的函数定义几乎完全一样,区别仅在于方法的第一个参数必须是self
'''
'''
class Cat:#创建了一个对象
def eat(self):#定义了一个方法
print("eat fish")

def drink(self):#又定义了一个方法
print("like drink water")

tom=Cat()#创建了一个tom对象--------------创建对象的实质是什么呢?在内存中开辟了一个空间
tom.eat()#这个对象来调用两个方法
tom.drink()
'''

# 在面向对象中,引用的概念同样适用
# class Cat:#创建了一个对象
# def eat(self):#定义了一个方法
# print("eat fish")
#
# def drink(self):#又定义了一个方法
# print("like drink water")
#
# tom=Cat()
# tom.name="Tom"#临时增加一个属性,这个方法不推荐使用
# tom.eat()
# tom.drink()

# tom和lazy_cat是两只猫
# 使用相同的类创建不同的对象
# lazy_cat=Cat()
# lazy_cat.eat()
# lazy_cat.drink()
# lazy_cat2=lazy_cat#这俩是同一只猫,所以

# class Cat:#创建了一个对象
# def eat(self):#定义了一个方法
# print("%s eat fish"%self.name)
#
# def drink(self):#又定义了一个方法
# print("%s like drink water"%self.name)
#
# tom=Cat()
# tom.name="Tom"#虽然很方便,但是开发中并不经常使用在类的外部添加属性
# # 对象包含哪些属性,应该封装在类的内部
# tom.eat()
# tom.drink()


'''
当使用类名创建对象时,会自动执行以下操作;
1.为对象在内存中分配空间----创建对象
2.为对象的属性设置初始值-----初始化init方法
__init__方法是专门用来定义一个类具有哪些属性的
使用类名创建对象的时候,会自动调用__init__()方法
在初始化方法中定义属性
self.属性名=属性值
'''

'''
class Cat:
def __init__(self,new_name):
print("这是一个初始化方法")
# self.name="TOM"#编写代码的时候是有智能提示的,不希望把名字固定死,可以增加一个形参,然后传值
self.name=new_name#增加一个形参,这样就可以随意传值
def est(self):
print("%s like eat fish"%self.name)#初始化方法定义的name全部的地方都可以使用

tom=Cat("tom")
tom.est()
print(tom.name)#这里输出的是tom的初始值
lazy_cat=Cat("大懒猫")
lazy_cat.est()

改造初始化方法
在开发中,若希望在创建对象的同时,就设置对象的属性,可以对__init__方法进行改造
1.把希望设置的属性值定义成__init__方法的参数
2.方法内部使用self.属性名=形参 接收外部传递的参数
3.在创建对象的时候,使用类名(属性1,属性2,属性3...)调用
'''
'''
__del__它也是一个内置方法
'''

# class Cat:
# def __init__(self,name):
# self.name=name
# print("%s l come"%name)
# def __del__(self):
# print("%s l go"%self.name)
# # tom是一个全局变量
# tom=Cat("TOM")
# print(tom.name)
#
# del 关键字可以调用__del__方法
'''
生命周期
一个对象从调用类名()开始创建,生命周期开始
一个对象的__del__方法一旦被调用生命周期结束
在对象的生命周期内可以访问对象的属性,或者让对象调用方法
'''

'''
__str__方法
若在开发中,若希望print输出变量内容的时候能够打印自定义的内容,可以利用这个内置方法
但是这个方法的返回值必须是字符串类型
'''
# class Cat:
# def __init__(self,name):
# self.name=name
# print("%s l come"%name)
# def __del__(self):
# print("%s l go"%self.name)
#
# def __str__(self):
# # 这个方法必须返回一个字符串
# return "l am a cat[%s]"%self.name
# # tom是一个全局变量
# tom=Cat("TOM")
# print(tom)


'''
封装:
1.封装是面向对象编程的一个特点
面向对象的第一步就是将属性和方法封装到一个抽象的类中
外界使用类创建对象,然后使用对象调用方法
对象方法的细节都被封装在类的内部
'''

'''
class Person:
# 初始化
def __init__(self,name,weight):
# self.属性=形参
self.name=name
self.weight=weight
# 描述

def __str__(self):
return "my name %s weight %s"%(self.name,self.weight)

def run(self):
print("%s 爱跑步,锻炼身体"%self.name)

def eat(self):
print("%s 是一个吃或"%self.name)
self.weight+=1
# 在对象的方法内部可以直接调用方法的属性
xiaoming=Person("XIAOMING",75.0)
xiaoming.run()
xiaoming.eat()

print(xiaoming)
'''# example


'''
class Person:
# 初始化
def __init__(self,name,weight):
# self.属性=形参
self.name=name
self.weight=weight
# 描述

def __str__(self):
return "my name %s weight %s"%(self.name,self.weight)

def run(self):
print("%s 爱跑步,锻炼身体"%self.name)

def eat(self):
print("%s 是一个吃或"%self.name)
self.weight+=1
# 在对象的方法内部可以直接调用方法的属性
xiaoming=Person("XIAOMING",75.0)
xiaoming.run()
xiaoming.eat()
xiaomei=Person("xiaomei",45.5)
xiaomei.eat()
xiaomei.run()
print(xiaomei)
print(xiaoming)
# 同一个类创建多个对象,对象直接的属性是互不影响的
'''

# 开发中,被使用的类总是先开发

'''
class HouseItem:
def __init__(self,name,area):
self.name=name
self.area=area

def __str__(self):
return "[%s] zhandi %.2f"%(self.name,self.area)


class House:
def __init__(self,type,area):

self.type=table
self.area=area

self.freearea=area
self.item_list=[]

def __str__(self):
# python能够自动将一对括号的代码链接在一起
return ("huxing: %s\n zongmianji:%.2f[shengyu :%.2f]\n jiaju:%s"
%(self.type,self.area,
self.freearea,self.item_list))

def AddItem(self,item):
print("要添加%s"%item)

#创建家具
bed=HouseItem("XIMENGSI",4)
chest=HouseItem("yigui",2)
table=HouseItem("canzhuo",1.4)
print(bed)
print(chest)
print(table)

# 创建房子对象

myhouse=House("两室一厅",60)
myhouse.AddItem(bed)
myhouse.AddItem(chest)
myhouse.AddItem(table)
print(myhouse)
'''

class HouseItem:
def __init__(self,name,area):
self.name=name
self.area=area

def __str__(self):
return "[%s] zhandi %.2f"%(self.name,self.area)


class House:
def __init__(self,type,area):

self.type=table
self.area=area

self.freearea=area
self.item_list=[]

def __str__(self):
# python能够自动将一对括号的代码链接在一起
return ("huxing: %s\n zongmianji:%.2f[shengyu :%.2f]\n jiaju:%s"
%(self.type,self.area,
self.freearea,self.item_list))

def AddItem(self,item):
print("要添加%s"%item)
#1.判断家具的面积
if item.area>self.freearea:
print("%s too big"%item.name)
return

#2.将家具的名称添加到列表中
self.item_list.append(item.name)
#计算剩余面积
self.freearea-=item.area

#创建家具
bed=HouseItem("XIMENGSI",40)
chest=HouseItem("yigui",2)
table=HouseItem("canzhuo",1.4)
print(bed)
print(chest)
print(table)

# 创建房子对象

myhouse=House("两室一厅",60)
myhouse.AddItem(bed)
myhouse.AddItem(chest)
# myhouse.AddItem(table)
print(myhouse)
posted @ 2018-11-23 11:05  高文星星  阅读(195)  评论(0编辑  收藏  举报