day 15 面相对象

day 15 面相对象

编程思维

根据面对问题不同人呈现出来的思维模式不同,可以将编程思维分为三种:

  1. 面相过程编程(穷人思想) — 遇到问题马上想到解决这个问题的具体逻辑和步骤

  2. 函数式编程(小资思想) — 遇到问题马上想到有没有一个已经存在的函数可以解决这个问题,如果没有,自己造一个

  3. 面向对象编程(富豪思想) — 遇到问题马上想到有没有一个具有这个功能的对象,如果没有就造对象

一个函数只具备一个功能。

一个对象可以同时具有多个功能。(一个对象可以绑定多个函数,还可以保存多个数据)

类和对象

1. 什么是类?什么是对象?

类就是拥有相同功能或者相同属性的对象的集合

对象就是类的实例

例如:如果人是类,则每一个人都是人的对象,余老师是对象,我是另一个对象
杯子是类,则我的紫色保温杯是杯子的对象, 我的矮的玻璃杯是杯子的另一个对象
斗地主游戏是类,则每一盘已经开启的游戏这个活动都是斗地主游戏的对象

2. 定义类 — 创建类

类是一个抽象的概念,而对象是一个能用的具体的表现

定义类:用代码来描述你这个类是拥有那些相同功能(一个功能就用一个函数描述)和哪些相同属性(属性用变量保存)的对象的集合。

  1. 定义类:用代码来描述你这个类是拥有那些相同功能(一个功能就用一个函数描述)和哪些相同属性(属性用变量保存)的对象的集合。
  2. 语法:
    class 类名:
    类的说明文档
    类的内容(包含方法(功能)和属性)

类名后也可以加一个括号:
class 类名(父类):
类的说明文档
类的内容(包含方法(功能)和属性)

  1. 说明:
    a. class — 关键字;固定写法
    b. 类名 — 由程序员自己命名
    两要求:是标识符;不是关键字
    规范:见名知义; 不使用系统的函数名、类名、模块名; 采用驼峰式命名(必须是大驼峰),所有单词首字母大写
    c. 类的说明文档 — 本质就是一个多行注释
    d. 类的内容 — 包含定义在类中的函数(方法)和定义在类中的变量(属性)
    方法包括:对象方法、类方法、静态方法
    属性包括:类属性、对象属性

    # user_name  --- PEP8
    # userName  --- 小驼峰
    # UserName  --- 大驼峰
    
3. 创建对象

对象是通过类来创建的

语法:类名()

dog1 = Dog()
dog2 = Dog()
print(dog1, dog2)

# <__main__.Dog object at 0x0000016FAAA6F220> <__main__.Dog object at 0x0000016FAAA6F190>
# at 后面是地址,若地址不同,则数据是不同的数据

方法

定义在类中的函数就是方法

对象方法:直接定义在类中的函数就是对象方法

  • 使用:对象.xxx() 在调用使用时需要先 创建对象
  • 特点:自带参数self, 调函数的时候不能传参,系统会自动将当前对象传给self(谁调用,self就指向谁)
    调用时也可以有其他参数,加在self后即可,调用时给除了self不用管以外还是该传参传参

类方法:在定义的函数前加装饰器 @classmethod

  • 使用:类名.xxx
  • 特点:自带参数cls,调用函数时cls不需要传参,系统会将当前类传给cls

静态方法:在定义的函数前加装饰器 @staticmethod

  • 使用:类名.xxx

  • 特点:没有特点

    一个装饰器只管一个函数,如果需要多个类方法,需要在每个类方法的前面都加上装饰器

如果在类中定义的方法需要用到类中的对象属性,则用对象方法;

如果在类中定义的方法需要用到类中的类属性,则用类方法;

如果在类中定义的方法需要用到类中的对象属性和类属性则用对象方法

如果在类中定义的方法不需要用到任何属性,则用静态方法

class A:
    # 对象方法
    def func1(self):
        print(f'self: {self}')
        print('对象方法')

    def func2(self,a):
        print(f'self: {self}')
        print('对象方法')

    # 类方法
    @classmethod
    def func3(cls):
        print('类方法')

    # 静态方法
    @staticmethod
    def func4():
        print('静态方法')
# ---- ---- ---- 对象方法 ---- ----- ------ ------ ----- |
# 调用:对象.xxx()  需要先创建对象:对象=类名()
a1 = A()
# print(a1)
a1.func1()  # 此时self = a1

a2 = A()
a2.func1()  # 此时self = a2
# 发现系统会自动给self传参,且传的参self与a1的地址相同(即是同一个值)
# 调用对象时不用传参,系统会将当前调用的对象作为实参传给self
b1 = A()
b1.func2(10)  # 对象方法 10 100


# ----- ---- ----- ----- 类方法  ----- ----
A.func3()


# ----- ---- ------- --- 静态方法 -- ---- --
A.func4()

# 例如数学类没有对象,但有很多数学相关的方法,可以用静态方法
# 即是本身和类没有说明关系,但为了让方法更有归属感而这样定义类

init方法

魔法方法的特点:

a. 函数名以 __开头,并且以__结尾
b. 魔法方法不需要程序员自己调用,系统会在特定情况下自动调用

2) 两个常见的魔法方法
a. __init__ 
如果在类中添加了__init__方法,那么在创建当前类的对象时会自动调用这个方法
创建对象的时候需不需要实参,需要几个实参,由类中的__init__决定
# 用于 创建对象属性
b. __repr__ 
在类中添加了这个方法,则最后返回什么,打印对象时就输出什么(必须是字符串类型)

如果类中添加了__repr__方法,打印类的对象时会自动调用这个方法,并将这个方法的返回值作为打印结果打印
在类中添加__repr__方法的时候, 这个方法必须是字符串。
class A:
    def __init__(self): # 可以自己添加形参
        print('init被调用')

    def __repr__(self):
        return 'abc'


a1 = A()
a2 = A()
print(a1)  # abc

class B:
    def __init__(self, m, n):
        print(f'm:{m},n:{n}')


b1 = B(10, 3)  # m:10,n:3

如果对打印结果不满意,可以用repr修改打印结果

class Student:
    def __init__(self,name, age=18,gender='男'):
        self.name=name
        self.age = age
        self.gender = gender

stu1 = Student('小明')
stu2 = Student('小花', age = 17, gender = '女')
print(stu1)  # <__main__.Student object at 0x000002863A47B400>
print(stu2)  # <__main__.Student object at 0x000002863A47B2B0>

# ------------------  添加__repr__后 -----------------------
class Students:
    def __init__(self, name, age=18, gender='男'):
        self.name = name
        self.age = age
        self.gender = gender

    def __repr__(self):
        return f'姓名:{self.name},年龄:{self.age}, 性别:{self.gender}'


stus1 = Students('小明')
stus2 = Students('小花', age=17, gender='女')
print(stus1)  # 姓名:小明,年龄:18, 性别:男
print(stus2)  # 姓名:小花,年龄:17, 性别:女

属性

  1. 类属性

    直接定义在类中的变量就是类属性

    类名.xxx

    如果属性的值不会因对象不同而不同,就用类属性。例如圆周率,所以圆的圆周率都相同

  2. 对象属性

    以’self.属性名 = 属性值’ 的形式定义在_ init __的方法中

    对象.xxx 使用前须先创建对象

    如果属性的值会因对象的不同而不同则用对象属性

class A:
    # 类属性
    a = 10
    name = '张三'

    # x、n 是对象属性
    def __init__(self):
        self.x = 100
        self.n = 'hello!'


# 使用类属性:类名.xxx
print(A.a)  # 10
print(A.name)  # 张三

# 使用对象属性:
a1 = A()
print(a1.x)  # 100
print(a1.n)  # hello!


class Circle:
    # 所以圆的圆周率都一样,所以用类属性
    pi = 3.1415926

    def __init__(self, r=0):
        self.r = r
        # 圆的半径会因圆不同而不同,所以用对象属性

    # 如果对象方法中需要用到对象属性,由self作为对象来提供
    # 如果需要的数据或变量,类中没有则需要增加形参
    def area(self):
        # 圆面积
        return Circle.pi * self.r ** 2

    def perimeter(self):
        # 圆周长
        return Circle.pi * self.r * 2

对象属性赋值方法:

  1. 直接赋值 赋一个固定的值,会导致创建的每个对象都相同,还需要创建后重新赋值(不推荐)
  2. 在定义时给予形参,调用时赋值
  3. 在定义时给予形参并赋默认值。调用时不用默认值则重新赋值即可
class Dog:
    def __init__(self, name, gender, breed, age=3):
        # self.name = '财财'  # 赋一个固定的值, 会导致创建的狗都叫财财
        self.name = name  # 在创建时给形参,这样名字可以在函数外给
        self.age = age  # 可以在创建时给形参并赋默认值
        self.gender = gender
        self.breed = breed

# 赋一个固定的值,则每次都需要改名
# dog1 = Dog()
# dog1.name = '小黑'

dog1 = Dog('小黑','男', '土狗')
print(dog1.name)  # 小黑

继承

继承:让子类直接拥有父类的属性和方法

子类 — 继承者

父类 — 被继承的类

语法

class 类名(父类1,父类2……):

​ 类的说明文档‘

​ 类的内容

注意:如果定义类的时候没有写父类,那么这个类会默认继承 object(基类)

子类调用原理: 先看子类本身有没有调用的方法或属性,
没有就查父类,还没有查父类的父类,直到查到object还没有就报错

父类只能用其本身的内容
子类能用其父类、父类的父类、……、object(基类)以及其自身的内容

super().__ init _ _() — 调用当前类的父类的__init__(),解决父类对象属性在子类中不能使用的问题

class A:
    m = 100

    def __init__(self):
        self.n = 200

    def func1(self):
        print('对象方法')

    @classmethod
    def func2(cls):
        print('类方法')

    @staticmethod
    def func3():
        print('静态方法')

# B 继承 A 的一切
class B(A):
    # 添加新的内容
    x = 'hello'

    # z在子类中添加新的对象属性会导致从父类继承的对象属性不能使用
    def __init__(self):
        super().__init__()  # 调用当前类的父类的__init__(),解决父类对象属性在子类中不能使用的问题
        # super(B,self).__init__()
        self.y = 130

    # 添加新的方法
    def func4(self):
        print('新的对象方法')

    @classmethod
    def func5(cls):
        print('新的类方法')

    @staticmethod
    def func6():
        print('新的静态方法')

# B 能用 所继承类的所有内容
print(B.m)  # 100
b1 = B()
print(b1.n)  # 200
b1.func3()  # 静态方法
b1.func2()  # 类方法
b1.func1()  # 对象方法

# B 能用 自己独有的新添加的所有内容、
print(B.x)  # hello
print(b1.y)  # 130
b1.func4()  # 新的对象方法
b1.func5()  # 新的类方法
b1.func6()  # 新的静态方法

你可能感兴趣的:(java,python,jvm)