day17 面向对象基础
一.编程思想
1.编程思想:程序员在面对一个问题的时候首先想到的解决这个问题的想法
2.三种编程思想:
-
面向过程编程(穷人思想) - 会基本语法和逻辑
-
函数式编程(小资思想) - 会基本语法和逻辑还需要函数
-
面向对象编程(富豪思想) - 会基本语法和逻辑、函数还需要类和对象
# 练习:计算8的阶乘!
# 1 * 2 * 3 * 4 * ... * 8
s = 1
for x in range(1, 9):
s *= x
print(s)
import math
print(math.factorial(8))
def factorial(N):
s = 1
for x in range(1, N+1):
s *= x
return s
print(factorial(8))
二.认识类和对象
1.什么是类,什么是对象
类 - 类是拥有相同功能和相同属性的对象的集合。(是一个抽象的概念)
对象 - 对象是类的实例(是类的具体表现) (具体的)
从生活的角度:如果人是类,余婷就是对象、骆昊是另外一个对象
如果杯子是类,我手上的这个杯子就是对象
2. 定义类(创建类) - 用代码来描述清楚这个是到底是拥有哪些相同功能和哪些相同属性的对象的集合
功能 - 函数
属性 - 属性(保存数据的变量)
语法:
class 类名:
类的说明文档
类的内容(包括方法和属性)
注解:方法 - 定义在类中的函数
属性 - 定义在类中变量
说明:
class - 关键字;固定写法
类名 - 由程序员自己命名,必须符合名要求和规范
要求:是标识符;不能是关键字
规范:见名知义;采用驼峰式命名(由多个单词组成,单词间通过首字母大写来区分),第一个字母大写;
不使用系统的函数名、类名或者模块名
类的说明文档 - 本质就是多行注释
类的内容 - 由方法和属性组成
方法包括:对象方法、类方法和静态方法三种
属性包括:类属性(字段)和对象属性两种
class Student:
"""学生类"""
pass
class Dog:
"""狗类"""
pass
3.创建对象
对象是类的实例,创建对象必须通过类来创建。
语法:
对象 = 类名()
# 创建两个学生类的对象
s1 = Student()
s2 = Student()
print(s1, s2)
# 创建一个狗的对象
dog = Dog()
print(dog)
三.方法
类中的方法分为三种:对象方法、类方法、静态方法
1.对象方法
1)怎么定义:直接定义在类中的函数就是对象方法
2)怎么调用:通过对象来调用 - 对象.对象方法()
3)特点:用对象调用对象方法的时候,参数self不需要传参,系统会自动将当前对象传给self(谁去调用的这个方法当前对象就是谁)
2.类方法
1)怎么定义:定义函数前加@classmethod
2)怎么调用:通过类来调用 - 类.类方法()
3)特点:参数cls不需要传参,系统会自动将当前类传给cls
3.静态方法
1)怎么定义:定义函数前加@staticmethod
2)怎么调用:通过类来调用 - 类.静态方法()
3)特点:没有特点
class A:
"""无意义的类"""
def func1(self):
print('对象方法')
print(f'self:{self}')
@classmethod
def func2(cls):
print('类方法')
@staticmethod
def func3():
print('静态方法')
# 创建A的对象
a1 = A()
a2 = A()
print(f'a1:{a1}')
print(f'a2:{a2}')
# 用对象调用对象方法
a2.func1()
# 用类调用类方法
A.func2()
# 用类调用静态方法
A.func3()
list1 = [10, 20, 30]
list1.append(100)
4.类中函数的参数
class B:
def func1(self, x: int, y=10):
print(f'x:{x}, y:{y}')
@classmethod
def func2(cls, x, *, y, z):
print(f'x:{x}, y:{y}, z:{z}')
@staticmethod
def func3(x, y):
print(x, y)
b = B()
b.func1(100)
b.func1(100, 200)
b.func1(x=11, y=12)
B.func2(10, y=20, z=30)
四.构造函数和init方法
1.构造函数(了解) - 名字和类名一样,专门用来创建对象的函数就是构造函数
python中创建类的时候,系统会自动为我们创建这个类的构造函数。
补充:魔法方法的特点
1)方法名是__开头并以__结尾
2)魔法方法不需要程序员主动调用,在特定事件被触发后系统会自动调用
2.__init__方法
1)
“”"
当通过类创建对象的时候,类中__init__方法会被自动调用
(每次通过类创建对象的时候,类中的__init__都会被自动调用)
“”"
class Student:
def __init__(self):
print('init方法')
stu1 = Student()
stu2 = Student()
“”"
通过类创建对象的时候需不需要参数,需要几个参数,由这个类中的__init__决定。(看__init__除了self以外有没有额外的参数)
“”"
class Dog:
def __init__(self, x, y):
print('init方法:', x, y)
dog1 = Dog(10, 20)
dog2 = Dog(x=100, y=200)
五.属性
属性分为:对象属性和类属性(字段)
1. 类属性
1)怎么定义: 直接在类中定义一个变量,这个变量就是类属性
2)怎么使用: 通过类来使用 - 类.类属性
3)什么时候用: 属性不会因为对象不同而不一样就将这个属性定义成类属性
2. 对象属性
1)怎么定义: 以’self.属性名=值’的形式定义在__init__方法中
2)怎么使用: 通过对象来使用 - 对象.对象属性
3)什么时候用:属性会因为对象不同而不一样就将这个属性定义成对象属性
class A:
# x是类属性
x = 100
# y是对象属性
def __init__(self):
self.y = 200
# 通过类使用类属性
print(A.x)
A.x = 200
print(A.x)
# 通过对象使用对象属性
a = A()
print(a.y)
a.y = 300
print(a.y)
class Circle:
pi = 3.1415926
def __init__(self):
self.r = 0
3. __init__方法的扩展
1)如果类需要对象对象属性,就需要在类中添加__init__
2)可以通过在__init__中添加参数来实现创建对象的时候直接给属性赋值
class Person:
def __init__(self, name, gender='男'):
self.name = name
self.gender = gender
self.age = 0
p1 = Person('小花', '女')
p2 = Person('张三')
print(p1.name, p1.gender)
print(p2.name, p2.gender)
六.方法的选择
1. 选择
如果实现函数的功能需要对象(对象属性)就用对象方法;如果需要类就用类方法;如果都不需要就用静态方法
class Rect:
def __init__(self, width=0, height=0):
self.width = width
self.height = height
# 在实现对象方法的功能的时候如果需要的数据是对象相关数据,那么这个数据就由self来提供。
def area(self):
# self = r2
# self = r1
return self.width * self.height # return r2.width * r2.height -> return 5 * 8 -> return 40
r1 = Rect(10, 20)
r2 = Rect(5, 8)
print(r2.area())
print(r1.area())
# 练习:定义一个圆类,拥有属性半径和圆周率,拥有方法:求面积和求周长
class Circle:
# 类属性
pi = 3.1415926
def __init__(self, r):
self.r = r
def area(self):
# 这个类的对象能做的事情,self都可以做
return Circle.pi * self.r ** 2
def perimeter(self):
return 2 * Circle.pi * self.r
c1 = Circle(10)
c2 = Circle(2)
print(c1.area())
print(c2.perimeter())
作业
-
定义一个狗类和一个人类:
狗拥有属性:姓名、性别和品种 拥有方法:叫唤
人类拥有属性:姓名、年龄、狗 拥有方法:遛狗
class Dog: def __init__(self, name, gender, var): self.name = name self.gender = gender self.var = var class Person: def __init__(self, name1, years, dog): self.name1 = name1 self.years = years self.dog = dog cry_out = Dog('来福', '公', '泰迪') print(cry_out.name, cry_out.gender, cry_out.var) walk_the_dog = Person('常威', 20, cry_out) print(walk_the_dog.name1, walk_the_dog.years, walk_the_dog.dog)
-
定义一个矩形类,拥有属性:长、宽 拥有方法:求周长、求面积
class Rect: def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height def perimeter(self): return 2 * self.width * self.height c1 = Rect(10, 20) print(c1.area(), c1.perimeter())
-
定义一个二维点类,拥有属性:x坐标、y坐标 拥有方法:求当前点到另外一个点的距离
class Dot: def __init__(self, x, y): self.x = x self.y = y def distance(self, other): return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5 d1 = Dot(10, 20) d2 = Dot(20, 30) print(d1.distance(d2))
-
定义一个圆类,拥有属性:半径、圆心 拥有方法:求圆的周长和面积、判断当前圆和另一个圆是否外切
class Circle: pi = 3.1415926 def __init__(self, r1, x1, y1, ): self.r1 = r1 self.x1 = x1 self.y1 = y1 def area(self): return Circle.pi * self.r1 ** 2 def perimeter(self): return 2 * Circle.pi * self.r1 def excircle(self, other): if ((other.x1-self.x1) ** 2 + (other.y1 - self.y1) ** 2) ** 0.5 == self.r1 + other.r1: print('外切') else: print('不外切')
-
定义一个线段类,拥有属性:起点和终点, 拥有方法:获取线段的长度
class Lines: def __init__(self, x1, y1, x2, y2): self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 def lengths(self): return ((self.x1 - self.x2) ** 2 + (self.y1 - self.y2) ** 2) ** 0.5 l1 = Lines(0, 20, 35, 14) print(l1.lengths())