面向对象-python

#私有属性和私有方法
#子类的对象不能子阿自己的方法内部直接访问父类的私有属性和私有方法
#子类对象可以通过父类的共有方法间接访问到父类的私有属性或者私有方法
#私有属性,私有方法是对象的隐私,不对外公开,外界以及子类都不能直接访问

class test():
    def __init__(self,name,age):
        self.name=name
        self.__age=age
    def __message(self):
        print '姓名是[%s],年龄是[%d]' %(self.name,self.__age)
    def test(self):
        self.__message()
####################################
    def __init__(self,name,age):
        self.name=name
        self.__age=age
    def __message(self):
        print '姓名是[%s],年龄是[%d]' %(self.name,self.__age)
    def test(self):
        self.__message()

class B(A):
    pass

b=B('li',18)
b.test()

类结构
1.使用面向对象开发,第一步是设计类
2.使用 类名() 创建对象,创建对象的动作有两步
    1.在内存中为对象分配空间
    2.调用初始化方法__init___ 为对象初始化
3.对象创建后,内存中就有了一个对象的实实在在的存在--实例

因此:
1.创建出来的对象叫做类的实例
2.创建对象的动作叫做实例化
3.对象的属性叫做实例属性
4.对象调用的方法叫做实例方法

在程序执行时:
1.对象各自拥有自己的实例属性
2.调用对象的方法,可以通过self
    访问自己的属性
    调用自己的方法
结论:
1.每一个对象都有自己独立的内存空间,保存各自不同的属性
2.多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用传递到方法内部

多态:    不同的子类(这是之前提到的继承的知识)
    对象调用相同的方法,产生不同的执行结果

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 和 %s 快乐的玩耍'  % (self.name,dog.name)
        dog.game()

# 1.创建一个狗对象
 #wangcai = Dog('旺财')
 wangcai = Xiaotianquan('飞天神狗')
 # 2.创建一个人对象
 xiaoming = Person('小明')
 # 让小明和狗玩
xiaoming.game_with_dog(wangcai)

类属性
#类是一个特殊的对象
#Python中一切皆对象
#    class AAA: 定义的类属性属于类对象
#        obj1 =AAA: 属于实例对象
#        在运行程序时,类 同样会被加载到内存
#        在python中,类 是一个特殊的对象--类对象
#
#        除了封装 实例(对象) 的属性和方法外,类对象还可以有自己的属性和方法
#
#        通过 类名. 的方式可以直接访问类的属性或者调用类的方法
 

class Tool(object):
	count = 0
	def __init__(self,name):
		self.name = name
		Tool.count += 1
tool1 = Tool('斧头')
tool2 = Tool('榔头')
tool3 = Tool('梯子')
print Tool.count

class关键字下方可以定义类属性
类属性用于记录于这个类相关的特性
类方法就是针对类对象定义的方法
在类方法内部就可以直接访问类属性或者调用其他类方法

语法如下:
@classmethod
def 类方法(cls):
    pass

class Toy(object):
1.定义类属性
count = 0
	@classmethod
	def show_toy_count(cls):
		#cls.coun:在类方法的内部,访问当前的类属性
		print '玩具对象的数量 %d' % cls.count
	def __init__(self,name):
		self.name = name
		# 让类属性的值 +1
		Toy.count += 1
# 创建玩具对象
toy1 = Toy('乐高')
toy2 = Toy('玩具车')
toy3 = Toy('玩具熊')
 # 调用类方法
Toy.show_toy_count()
# 在方法的内部,可以直接访问类属性
#

静态方法:
静态方法
在开发时,如果需要在类中封装一个方法,这个方法:
    既不需要访问实例属性或者调用实例方法
    也不需要访问类属性或者调用类方法
这个时候可以把这个方法封装成一个静态方法

语法如下:
@staticmethod
def 静态方法():
    pass
静态方法需要修饰器@staticmethod来标识,告诉解释器这是一个静态方法
通过类名,调用静态方法

class Cat(object):
	@staticmethod
    # 静态方法不需要传递第一个参数:self
	def call():
		print '小猫喵喵叫~'
		 # 通过类名.调用静态方法
		 # 不需要创建对象,直接可以使用
Cat.call()

1.设计一个Game类
2.属性
    类属性,记录游戏的历史最高分(与这个游戏类有关系,与每次游戏无关)
    实例属性,记录当前游戏玩家的玩家姓名
3.方法:
    静态方法:方法show_help显示游戏帮助信息
    类方法:方法show_top_score显示历史最高分
    实例方法:方法start_game开始当前玩家的游戏

4.主程序步骤
    1.查看帮助信息
    2.查看历史最高分
    3.创建游戏对象,开始游戏

class Game(object):
    # 1.记录历史最高分
    top_score = 0
    def __init__(self,player_name):
        self.player_name = player_name

    @staticmethod
    def show_help():
        print '@#@!$@!$'

    @classmethod
    def show_top_score(cls):
        print '历史记录 %d' % cls.top_score

    def star_game(self):
        print '%s 开始游戏了' % self.player_name

#1.查看游戏帮助信息
Game.show_help()
# 2.查看历史最高分
Game.show_top_score()
# 创建游戏对象。开启游戏
game = Game('小明')
game.star_game()

案例小结:
1.实例方法:方法内部需要访问实例属性
2.类方法:方法内部只需要访问类属性
3.静态方法:方法内部不需要访问实例属性和类属性

提问:如果方法内部,既需要访问实例属性,又需要访问类属性,应该定义什么方法?
应该定义实例方法
因为,类只有一个,在实例方法的内部可以使用 类名.访问类属性

设计模式:

class MusicPlayer(object):
    def __new__(cls, *args, **kwargs):
        print '创建对象,分配空间'
        instance=object.__new__(cls)
        return instance
    def __init__(self):
        print '播放器初始化'

player1 = MusicPlayer()
print player1
player2=MusicPlayer()
print player2

输出:
创建对象,分配空间
播放器初始化
<__main__.MusicPlayer object at 0x7f59a3b2a050>
创建对象,分配空间
播放器初始化
<__main__.MusicPlayer object at 0x7f59a3b2a090>
#显然这个设计播放器不符合逻辑,因为如果打开两个歌曲会给他分配两个内存地址,意味这将会同时播放两首歌曲

class MusicPlayer(object):
    instance=None
    init_flag = False
    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance=object.__new__(cls)
        return cls.instance
    def __init__(self):
        if MusicPlayer.init_flag:
            return
        print '播放器初始化'
        MusicPlayer.init_flag=True

player1 = MusicPlayer()
print player1

player2 = MusicPlayer()
print player2

#这样设计,将只会分配一个地址,并且只会初始化一次

猜你喜欢

转载自blog.csdn.net/u010489158/article/details/81168538