面向对象

  • 面向对象
  • 1.类
  • 2.类的定义
  • 2.对象
  • 2.1对象的概念
  • 实例化对象
  • 3.属性
  • 3.1类属性
  • 3.2 对象属性
  • 4 . 方法
  • 4.1 对象方法 -- ①
  • 4.2 对象方法 -- ②
  • 4.3 魔术方法


面向对象

前面我们讲到基本数据类型用来表示最常见的信息,但是信息有无穷多种,为了更好的表达信息,我们可以创建自定义数据类型。

1.类

一种数据类型就是类,例如整数,浮点数,字符串。自定义类就是为了自定义数据类型

2.类的定义

python中通过关键字 class 可以定义一个自定义数据类型(自定义类),基本语法如下:

class 类名:
	属性
	方法

类名:
规则:同变量名
规范:一般使用大驼峰表示(每个单词第一个字母大写)

案例:
例如:创建一个point类用于表示平面坐标系中的一个点。
创建一个类(数据类型)

class point:
	'''
	表示二维平面里的一个点
	'''
print(point, type(point))   # <class '__main__.point'> (当前文件下的point类) <class 'type'> (类型是 '类')

规范 : 类的定义要离上面的代码要隔两个空行。

2.对象

2.1对象的概念

某种数据类型的一个具体的数据称为这个类的一个对象或者实例,通过类创建对象叫做实例化。 举个例子:女朋友就是类,你的女朋友就是一个对象
所谓的面向对象,就是把一些数据抽象成类的思想
python是一门面向对象的编程语言,python中一切皆对象。
前面学习的函数也是python中的一个类,定义的某个函数就是函数类的一个具体实例。

实例化对象

创建对象:根据数据类型(类)创建一个对象,这个过程就叫做实例化。
基本数据类型有特殊的实例化方法
自定义数据类型创建对象的方法 : 类名(参数)
理解为:把类当作一个函数去调用

class GirFriend:
	'''
	女朋友
	'''
g = GirFriend()
print(g, type(g)) 
默认情况下它的值是一个内存地址,
#  <__main__.GirFriend object at 0x00000260C5C37908> <class '__main__.GirFriend'> # 当前文件下 GirlFriend 类

面向对象:为了更好地处理数据,我们自定义数据类型来包装这个数据。

3.属性

类和对象的特征数据称为属性

3.1类属性

类特征称为类属性,所谓的类属性就是这个数据类型共有的特征。

直接定义在类中的变量(与class语句只有一个缩进),称为类属性
定义类属性

class point:
	'''
	表示二维平面里的一个点
	'''
	name = '点'
p = point()

访问类属性:有两种方法
①.类名.属性名

print(point.name)   # 点

②.对象.属性名

p = point()
print(p.name)  #  点
print(p.age)  # 报错 AttributeError: 'point' object has no attribute 'age'
# 访问没有的属性,会报错。

注意:如果你访问一个不存在的属性 它就会报错

3.2 对象属性

对象的特征数据称为对象属性
女朋友是类,这个类共有的属性,一般会定义为类属性。
例如:所有的女朋友性别都是女
你的女朋友是对象,这个对象特有的属性一般会定义为对象属性
通过类可以访问类属性,通过对象也可以访问类属性,类属性是类和对象的公有属性。
举例: 女朋友的性别是女性,你的女朋友性别也是女性
但是对象属性 只能通过对象访问
举例:你的女朋友叫小花,但是 不是所有的女朋友都叫小花,小花是对象属性,通过类无法访问对象属性。
3.2.1 对象属性的定义
对象属性一般定义在构造方法中,详见下面构造方法一节。
通过句点法 动态地给对象增加属性 (对象.对象属性 = )以赋值的方式可以直接定义对象属性
对象.属性名 = 值

class point:
    '''
    表示二维平面里的一个点
    '''
    name = '点'

p = point()
p.x = 0
p.y = 0

访问对象属性
对象.属性名
通过一个对象去访问一个属性的时候,首先找自己有没有这个属性,有就返回,没有就找他的类的属性,如果还没有就报错。所以,如果一个对象属性名和类属性名重名了,访问只会返回对象属性。

print(p.x, p.y)  # 0 0

4 . 方法

定义在类里的函数叫方法,通过调用的方式的不同,分为对象方法,类方法,静态方法和魔术方法。
属性(特征)是类或者对象的某个具体的值,比如女朋友的属性,就是他的身高,体重,名字 这些具体的值
方法可以理解为她的功能,女朋友可以陪你吃饭,可以陪你逛街,可以执行某些动作,实现某些功能。

4.1 对象方法 – ①

定义在类中的普通方法,一般通过对象调用对象方法

class point:
    '''
    表示二维平面里的一个点
    '''
    name = '点'

p = point()
p.x = 0  # 点的x轴坐标
p.y = 0  # 点的y轴坐标
print(p)

'''
需求1:写一个函数,接收一个point的对象,打印一个点 输出形如 点(x,y)
'''
def my_print(point):
    '''
    打印point 类的对象,输出 点(x,y)
    :param point:
    :return:
    '''
    print('点({},{})'.format(point.x, point.y))

my_print(p)

需求 2 :写一个函数,计算两个点的距离

(x1 , y1) (x2, y2) 他们的距离,坐标的差的平方和开根号
((x1 - x2)^2 + (y1 - y2)^2)^0.5
def distance(p1, p2):
    '''
    计算点p1和p2的距离
    :param p1: Point的对象
    :param p2:
    :return:
    '''
    return ((p1.x - p2.x)**2 + (p1.y-p2.y)**2)**0.5
p2 = point()
p2.x = 1
p2.y = 1

res = distance(p, p2)
print(res)    # 1.4142135623730951

总结: my_print, distance 都接受 1个或多个point类的对象作为参数
这两个函数与point类密切相关
分开定义,相关性就不明显
所以可以把这两个函数定义在类的里面,显示的相关

4.2 对象方法 – ②

直接定义在类里的函数就是对象方法
怎么调用呢?有两种方法

  • 类.方法名调用 这种方式和普通的函数调用没有什么区别,但是我们不用
  • 对象.方法名 这种方式才是正确的调用方式,但是这样去有隐藏在背后的操作
    当通过对象去调用对象方法的时候,会把对象本身隐式的传给第一个参数
    所以,对象方法的第一个参数,一般定义为self,表示自己。
class point:
    '''
    表示二维平面里的一个点
    '''
    name = '点'

p = point()
p.x = 0  # 点的x轴坐标
p.y = 0  # 点的y轴坐标
	def my_print(self):
    '''
    打印point 类的对象,输出 点(x,y)
    :param point:
    :return:
    '''
    print('点({},{})'.format(self.x, self.y))
	
	def distance(self, p2):
    '''
    计算点p1和p2的距离
    :param p1: Point的对象
    :param p2:
    :return:
    '''
    return ((self.x - p2.x)**2 + (self.y-p2.y)**2)**0.5
    
p1 = point()
p1.x = 0
p1.y = 0

p2 = point()
p2.x = 1
p2.y = 1 

# 通过类调用
point.myprint(p1)
res = point.distance(p1,p2)
print(res)

# 通过对象调用
p1.my_print()
res = p1.distance(p2)    # p2.distance(p1)
print(res)

可以打断点去调试一下
刚开始学习面向对象的时候,不要动脑筋,刚开始就去理解它的字面意思就可以了。

4.3 魔术方法
魔术方法,一般实现特殊的功能,它的命名方式: __方法名__
1 . 构造方法,或者叫做初始话方法
  __init__ 
  定义对象的属性,它接收实例化时传入类名的参数
  当对象创建的时候,它自动调用