Python类与面向对象

Yanni / 2023-08-06 / 原文

目录
  • 一、面向对象的概念
    • 1.是什么?
    • 2.特点
  • 二、类与对象
    • 1.类的定义
      • (1)类的定义格式
      • (2)类的定义形式
    • 2.类的构造(创建create)方法
    • 3.类的实例化(类的对象化)
      • (1)对象的创建格式
      • (2)访问对象成员
    • 4.成员的定义及访问
      • (1)私有变量和方法的访问——只允许本类使用,子类和外部都不能访问
      • (2)公有变量和方法的访问——外部可以访问
  • 三、继承
    • 1.单继承
    • 2.多继承

笔记风格的三条建议:

  1. 结构清晰、细化(看着舒服便于查找)
  2. typota风格设置,善用引用、序号、点(看着美观)
  3. 多放图片,大小合适和大小一致(看着美观)

笔记内容的三条建议:

  1. 保证内容正确性,多测试(集百家之言并有自己理解)
  • (1)看懂
  • (2)善用比喻能讲懂
  • (3)总结经验
  1. 尽量用自己的代码做测试(便于理解和熟悉代码)

  2. 一个问题一个笔记,学会根据这个知识点拓展(丰富内容)

一、面向对象的概念

1.是什么?

​ 简单点说,“面向对象”是一种编程范式,而编程范式是按照不同的编程特点总结出来的编程方式。俗话说,条条大路通罗马,也就说我们使用不同的方法都可以达到最终的目的,但是有些办法比较快速、安全且效果好,有些方法则效率低下。同样,编程也是为了解决问题,而解决问题可以有多种不同的视角和思路,前人把其中一些普遍适用且行之有效的编程模式归结为“范式”。

常见的编程范式有:

  • 面向过程编程

把事情拆分成几个步骤(相当于拆分成一个个的方法和数据),然后按照一定的顺序执行。

  • 面向对象编程

面向对象会把事物抽象成对象的概念,先抽象出对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法。

2.特点

封装:封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节,避免了外界直接访问对象属性而造成耦合度过高及过度依赖,同时也阻止了外界对对象内部数据的修改而可能引发的不可预知错误。

继承:继承不仅增强了代码复用性,提高了开发效率,也为程序的扩充提供了便利。在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是数据组织和分类行之有效的方法,它降低了创建对象、类的工作量。

多态:多态指同一属性或行为在父类及其各派生类中具有不同的语义,面向对象的多态特性使开发更科学、更符合人类的思维习惯,能有效地提高软件开发效率,缩短开发周期,提高软件的可靠性。

注:Python 语言在设计之初,就定位为一门面向对象的编程语言,“Python 中一切皆对象”就是对 Python 这门编程语言的完美诠释。

二、类与对象

1.类的定义

Python 类是由类头(class 类名)和类体(统一缩进的变量和函数)构成。

(1)类的定义格式
class 类名:
	属性名 = 属性值  # 定义属性
	def 方法名(self,形参1,形参2,...,形参N):  # 定义方法 方法中有一个指向对象的默认参数self
		方法体

class Rectangle:
    name = "张三" # 类成员变量
    def __init__(self, width1, height1): # 实例变量
        self.width = width1
        self.height = height1

self关键字是成员方法定义的时候,必须填写的

  • 它用来表示类对象本身的意思
  • 当我们使用类对象调用方法的时候,self会自动被python传入
class Person:
    def __init__(self, name1):
        self.name = name1

    def say_hello(self):
        print(f"Hello, my name is {self.name}.")

# 创建一个 Person 对象
p = Person("Alice")

# 调用对象的方法
p.say_hello()

当我们创建一个 Person 对象 p,并调用 p.say_hello() 时,输出将是 Hello, my name is Alice.。这是因为 self 在调用方法时被自动传入,并指向当前的 Person 对象。

  • 在方法内部,想要访问类的成员变量,必须使用self
  • self关键字,尽管在参数列表中,但是传参的时候可以忽略它。

类的成员变量可以在类的任何方法内部使用,必须通过实例名进行访问。

class Rectangle:
    name = "张三"  # 类成员变量

    def __init__(self, width1, height1):  # 实例变量
        self.width = width1
        self.height = height1
        self.name = "旺旺"

# 创建一个 Rectangle 对象
a = Rectangle(5, 3)

print(a.name)  # 输出: 旺旺
print(Rectangle.name)  # 禁止使用

self函数指代类本身,因此在类中定义函数时必须使用self这个参数

下面是一个实例:

image-20230806111404202

此时报错,是因为定义的add函数,是属于Rectangle类的,所以定义的时候第一个参数必须是self这个参数

正确操作如下:

image-20230806111232854

总结:在类里边定义类本身的函数,函数必须加self作为第一个参数,如果不加self它就报错

(2)类的定义形式
# class Hero:  # 经典类(旧式类)定义形式
# class Hero():

class Hero(object):  # 新式类定义形式

    # 方法
    def info(self):
        print("英雄各有见,何必问出处。")

定义类时有2种形式:新式类和经典类,上面代码中的Hero为新式类,前两行注释部分则为经典类;

  • objectPython 里所有类的最顶级父类;

  • 类名的命名规则按照大驼峰命名法

  • info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量 这个变量指向了实例对象

2.类的构造(创建create)方法

Python 类有一个名为 __init__() 的方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。

构造方法的作用是每当创建一个类的实例对象时,Python 解释器都会自动调用它。即该方法在类实例化时会自动调用。

注意:

  • 方法名开头和结尾各有 2 个下划线,且中间不能有空格。
  • __init__() 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数。
  • 即便不手动为类添加任何构造方法,Python 也会自动为类添加一个仅包含 self 参数的默认构造方法。

示例代码如下:

class MyClass:
    """一个简单的类实例"""
    name = "赵云"

    # 构造方法
    def __init__(self):
        print("调用构造方法")
        
    def m1(self):
        return 'hello class'

# 实例化类
c = MyClass()

# 访问类的属性和方法
print("属性 i 为:", c.name)
print("调用 m1方法,输出为:", c.m1())

输出结果为:

调用构造方法
属性 i 为: 赵云
调用 m1方法,输出为: hello class

3.类的实例化(类的对象化)

类定义完成后不能直接使用,程序中的类需要实例化为对象才能实现其意义。

创建类对象的过程,称为类的实例化。

(1)对象的创建格式
对象名=类名()
例:tmp_ex_guid = TGuid_StopeClass()  # 创建一个实例
(2)访问对象成员
对象名.变量名    # 访问对象属性
例:tmp_ex_guid.warning
对象名.方法()  # 访问对象方法
例:tmp_ex_guid.output()
4.成员的定义及访问

在一个类中,有三种不同访问属性的成员:public、protected、private

在类的内部(类的声明和类的定义)可以访问public、protected、private所有成员
在类的外部(对象和其他函数)不能访问private和protected成员

protected类型只允许本类和子类访问

(1)私有变量和方法的访问——只允许本类使用,子类和外部都不能访问

私有变量定义时在类成员之前添加双下划线(__)来限制成员的访问权限,语法格式如下:

class PersonInfo:
	__weight = 55             # 私有属性
	def __info(self):         # 私有方法
		print(f"我的体重是:{__weight}")   
        
    def get_weight(self):
        print(f'体重:{self.__weight}kg')

1)访问私有属性

私有属性可在公有方法中通过指代类本身的默认参数self访问,类外部可通过公有方法间接获取类的私有属性。

class PersonInfo:
    __weight = 65  # 私有属性

    def get_weight(self):  # 公有方法
        print(f'体重:{self.__weight}kg')  # 通过self参数访问私有变量
p = PersonInfo()  # 创建类的实例
p.get_weight()  # 调用get_weight方法

输出结果为:

体重:65kg

在此例中,公有方法用于获取并打印私有属性____weight的值,在方法体内部,使用self.____weight来访问私有属性weight,并通过print语句将其打印出来

2)访问私有方法

私有方法同样在公有方法中通过参数self访问。

class PersonInfo:
    __weight = 65  # 私有属性

    def __info(self):  # 私有方法
        print(f"我的体重是:{self.__weight}")

    def get_weight(self):  # 公有方法
        self.__info()  # 通过self参数访问私有方法

p = PersonInfo()   # 创建类的实例
p.get_weight()    # 访问公有方法get_weight()

输出结果为:

我的体重是:65

实例操作:以私有变量为例

image-20230806120327277

说明私有变量只允许本类访问:

image-20230806122234006
(2)公有变量和方法的访问——外部可以访问

在Python中,公有的变量和方法可以通过类的实例来访问;如果是在类的内部则直接使用self点的形式直接使用

1)访问公有变量

一个例子:

image-20230806112902574

再举个简单的实例:

class MyClass:
    def __init__(self):
        self.public_variable = 10

my_instance = MyClass() # 类的实例化
print(my_instance.public_variable)  # 输出: 10

2)访问公有方法

class MyClass:
    def public_method(self):
        print("This is a public method.")

my_instance = MyClass()
my_instance.public_method()  # 输出: This is a public method.

三、继承

1.单继承

单继承指的是子类只继承一个父类,其语法格式如下:

class 子类(父类):
class Amphibian: # 父类
    def features(self):
        print('幼年用腮呼吸')
        print('成年用肺兼皮肤呼吸')


class Frog(Amphibian):  # Frog类继承自Amphibian类
    def attr(self):
        print('我会呱呱叫')

frog = Frog()       # 创建类的实例化对象
frog.features()     # 使用父类的方法   
frog.attr()         # 使用自身的方法   

输出结果为:

两栖动物
幼年用腮呼吸
成年用肺兼皮肤呼吸
青蛙是两栖动物
我会呱呱叫

总结:子类继承父类之后,就拥有了父类继承的属性和方法,它既可以调用自己的方法,也可以调用从父类继承的方法。

2.多继承

多继承指的是一个子类继承多个父类,其语法格式如下:

class 子类(父类A,父类B):
class English:
    def eng_konw(self):
        print('具备英语知识')


class Math:
    def math_koow(self):
        print('具备数学知识')


class Student(English, Math):
    def study(self):
        print('学生的任务是学习')

s = Student()
s.eng_konw()   
s.math_koow()  
s.study()       

输出结果为:

具备英语知识
具备数学知识
学生的任务是学习

总结:一个子类可以有多个父类,一个父类也可以有多个子类

例如:

class TBase_Stope(TBase):
    函数体
class TZk_Bore(TBase):
    函数体
class TRock(TBase):
    函数体
class TBase(object): # object是最顶级的父类
    函数体