|
又过了两周,零零碎碎地把黑马大本营的面向对象看了一遍,按我的理解开始小结。 python号称支持完全面向对象,js也称一切都是对象,但js不敢说完全面向对象,关于这一点,还没来得及细想。学到这里出现一个问题,学了py的面向对象,js的面向对象有点模糊了,看样子有必要再回头看看js的面向对象,不过有了js的面向对象基础,理解py的面向对象少了许多障碍,学习过程中,深有感触,如果没有之前学的js基础,有许多面向对象的概念将无法理解,感谢妙味和达内,否则真要晕了! py的面向对象,第一个上来的就是“类”,通过类的定义,用类来创建对象(实例对象),比如定义一个猫类Cat,再用这个猫类来创建具体的猫,如叫tom的猫,叫lazy_cat的猫,这点上js不同,js不能定义类,但也有类这么一个东西,如Object、Array、Function、String等,这些是js已经定义好的类,通过new的方法就可以创建对象实例,如var arr=new Array(),创建了一个数组对象arr,arr对象具有Array类的相关属性和可以使用Array类提供的方法。 py类的定义用class关键字,如class
Cat:定义一个Cat类,有点象js的构造函数的原型定义,类名须用大驼峰命名,在类中用def关键字(与py定义函数一样)定义类的方法,不同普通函数的是,方法名后的括号里第一个参数要跟一个self或cls关键字,如def aa(self,…):定义aa方法,这个self和cls其实相当于js的this,js的this用法比较复杂,貌似py没有这个问题,这里还好理解this的意义,否则这个关不容易过。 定义类后,就可以使用类来创建实例对象,如tom=Cat(),即用Cat类创建了一个tom对象,创建好的对象在内存中保存,返回的引用指向self,tom对象拥有Cat类内部定义好的属性和方法,调用属性和方法就用tom.xx和tom.xx()。虽然py也可以用tom.yy来给tom对象添加新属性yy,不过黑马大本营不推荐这么做,js可以用tom.zz=function...来给对象添加新方法zz,好像py没有这种写法? py类中定义属性有两种情况: 一种是定义给实例对象用的,需要定义在__init__函数(或称方法)里(前后双下划线),如def __init__(self,参数):中,这个__init__方法在调用类创建对象时会自动调用,字面意思是初始化,在这个函数里定义属性如self.name=xx,即定义了一个name属性,值为xx,其中值也可以通过传参的方式传递,如 def __init__(self,name): self.name=name 这种属性是给用类创建的对象用的,即用该类创建的实例对象具有该属性,调用如tom.name(tom对象的name属性),除了外部调用,这种属性在类定义的内部也可以被调用,调用的方法如self.name,比如在Cat类定义一个方法,方法中调用name属性用self.name(同js的this.name);在 __init__中还可以定义一种私有属性,私有属性需要用双下划线开始,如__age=18,这个age属性不能在外面被调用(用类名+属性可以调用,但不推荐,我想私有属性就是为了内部调用的),在外调用(包括子类调用父类)如tom.age或tom.__age程序会报错,但能在类内部被调用,如self.__age。 第二种属性叫类属性,不需要定义在__init__方法里,直接在类中象普通变量一样定义,如count=0,这种属性在外部要用类名调用,如Cat.count,在类内部要用cls.count调用,这种属性是用给类自己的,如一个工具类,定义一个类属性count,用来统计用该类创建的对象数量,再比如一个游戏类,用类属性来纪录最高成绩,这种属性与具体对象没有什么关系(换句话说,就是对象没有必要设计这种属性)。 py类中定义方法同样,这里比属性略复杂些,慢慢理理: 1、一般方法(即实例方法),给实例对象用的,与函数的定义差不多,区别就是第一个参数一定要是self,方法中调用属性用self.xx(实例属性调用)或cls.xx(类属性调用),方法中调用其他方法用self.xx()。在外部调用实例方法,用对象名调用即可,如tom.xx()。记住无论调用什么方法,后面一定有一对括号! 2、内置方法,如定义属性用的__init__方法,这个是py有特殊用途的方法,除了__init__方法外,还有__str__(用于print输出对象时输出的字符串),__del__(用于对象退出时自动调用的方法),还有一个__new__(后述,有特殊用法。。。),这些方法是约定好了的,在特定的时间自动调用,如__init__方法就是当使用类创建实例对象时,自动调用,对对象进行初始化的。 3、私有方法,同私有属性,用双下划线,如def
__xxx(self):,这种方法在外也不能直接调用,如tom.__xxx()必然报错,在类的内部可以调用,如self.__xxx(),没有问题! 4、类方法,同类属性,特殊的是需要在定义前声明是类属性,用@classmethod,类方法的定义时第一个参数用cls而非self,这种类方法在外调用时要用类名,如Cat.xxx(),在内被调用时要用cls.xxx()。 5、静态方法,这种方法是在这种情况下定义,如一个方法不需要调用其他的方法和属性,即方法内部的东西是写死的。静态方法在定义前也要声明@staticmethod,调用同类方法,要用类名调用,如Cat.xxx()而非tom.xxx()
今天小结了关于py的类、实例对象的属性和方法定义、py的内置方法、私有属性和私有方法,类方法和静态方法。 补充:py要求定义类时最好指定一个基类,主要是区别于python2.x,所以需要写法如class Cat(object): 再补充一个案例,用一用本小结的知识点。设计一个 Game 类
属性:
定义一个 类属性 top_score 记录游戏的
历史最高分
定义一个 实例属性 player_name 记录
当前游戏的玩家姓名
方法:
静态方法 show_help 显示游戏帮助信息
类方法 show_top_score 显示历史最高分
实例方法 start_game 开始当前玩家的游戏
主程序步骤
1) 查看帮助信息
2) 查看历史最高分
3) 创建游戏对象,开始游戏 class Game(object): # 类属性,游戏最高分 top_score = 0 # 静态方法 @staticmethod def show_help(): print("帮助信息:让僵尸走进房间") # 类方法,方法中cls.top_score调用类属性 @classmethod def show_top_score(cls): print("游戏最高分是 %d" %
cls.top_score) def __init__(self, player_name): self.player_name = player_name def start_game(self): print("[%s] 开始游戏..." %
self.player_name) # 使用类名.修改历史最高分 Game.top_score = 999 # 1. 查看游戏帮助 Game.show_help() # 2. 查看游戏最高分 Game.show_top_score() # 3. 创建游戏对象,开始游戏 game = Game("小明") game.start_game() # 4. 游戏结束,查看游戏最高分
Game.show_top_score() |