没有对象的new一个对象。------JAVA
说面向对象之前,可以先看看面向过程编程,Python一般的用法都是面向过程编程,但是对于复杂需求,使用面向过程容易使程序过于复杂,不利于开发。
面向过程:
-
完成某一个需求的步骤从头到尾逐步实现
-
将某些功能独立的代码封装成一个个函数
-
最终的代码就是顺序的调用不同的函数
总的来说,面向过程注重步骤和过程,对于复杂的项目没有固定的套路,增加了开发的难度。
面向对象:
- 完成某一个需求前首先确定职责----要做的事情(方法)
- 根据职责确定不同的对象,在对象内部封装不同的方法(多个)
- 最终的代码就是顺序的让不同的对象调用不同的方法
总的来说,面向对象注重对象和职责,不同的对象需要承担不同的职责,对于复杂项目有固定的套路。
一. 类和对象
类和对象使面向对象编程的两个核心概念。
类相当于制造飞机时的图纸,负责创建对象。
对象是由类创建出来的具体存在,可以直接使用,相当于用图纸制造的飞机。由哪一类创建出来的对象,就拥有这一类中定义的属性和方法。
程序开发中,应该先有类,再有对象,类只有一个,但是对象可以有很多个。
类的设计:
开发中应该先分析需求,确定程序包含哪些类,如植物大战僵尸,向日葵类、豌豆射手类。
设计一个类,需要满足三大要素:
类名:这类事物的名字,满足大驼峰命名法(每一个单词首字母大写,没有下划线:HouseSell)
属性:这类事物具有什么样的特征
方法:这类事物具有什么样的行为
开发时先分析需求,通过提炼对象的名词,能找到类名,对象的特征就是类的属性,对象的行为(动词)就是类的方法。
举例:
小明今年18岁,身高1.75,每天早上跑完步,回家吃早饭
小美今年17岁,身高1.65,喜欢吃东西
那么分析一下,小明和小美就是两个对象,抽象出来他们都属于人类,所以类名可以定义为Person,根据三大要素来看,还需要找到类的属性,那么名字、年龄和身高就是一个人的特征,即为类的属性,最后跑和吃(动词)就是类的方法。
类名 | Person |
类的属性 | name,age,height |
类的方法 | run(),eat() |
二. 面向对象基础语法
dir()内置函数可以查看一个对象的所有属性和方法,格式为“__方法名__"的方法是python提供的内置方法/属性。
(1)类的定义
# 定义一个只包含方法的类
class 类名:
def 方法1(self, 参数列表): # 方法定义和函数相同,区别在于第一个参数必须是self
pass
def 方法2(self, 参数列表):
pass
# 创建对象
对象变量 = 类名()
举例:
小猫爱吃鱼,小猫要喝水
类名:猫 类的方法:吃、喝
class Cat:
def eat(self):
print("小猫吃鱼")
def drink(self):
print("小猫喝水")
Tom = Cat() # 创建一个叫Tom的对象 猫类
Tom.eat()
Tom.drink()
(2)方法中的self
在类封装的方法内部,self表示当前调用方法的对象自己,方法内部可以通过self.访问对象的属性,也可以通过self.调用其他对象的方法。
总的来说,由哪一个对象调用的方法,方法内的self就是对哪一个对象的引用(所谓引用就是指向的地址)。
class Cat:
def eat(self):
print("%s 爱吃鱼" % self.name)
tom = Cat()
tom.name = "Tom" # 给对象添加属性 但是不推荐这样给对象增加属性
tom.eat()
在类的外部,通过变量名.访问对象的属性和方法。
在类的内部,通过self.访问对象的属性和方法。
(3)初始化方法
__init__是专门用来定义一个类具有哪些属性的方法。
使用类名()来创建对象的时候会自动调用初始化方法。
在__init__方法内部使用self.属性名 = 属性初始值 就可以定义属性,定义属性之后再创建的对象都会具有该属性。
class Cat:
def __init__(self, name):
self.name = name
def eat(self):
print("%s 爱吃鱼" % self.name)
tom = Cat("Tom") # 创建对象给定初值
print(tom.name)
(4)私有属性和私有方法
在实际场景中,对象的某些属性或方法可能只希望在对象内部被使用,不希望外部被访问,则可以将方法、属性私有化。
在定义属性或者方法时,在名字前加两个下划线,就是私有属性或方法。
但是但是但是。。。Python中只是伪私有,使用__name来隐藏属性实际上只是将名字改成了_类名__名字的形式,如果使用_类名__名字还是能够访问到类内部的私有属性和私有方法。