Python面向对象

面向对象编程的三大特征:封装、继承和多态

类与实例的关系

类提供了把数据和功能绑定在一起的方式。创建新类时就等于创建了一种新的数据类型,这种数据类型称为对象类型,根据该数据类型可以创新该类型的新实例。

例子:定义一种新的类为Cat类,该类即是我们自定义的一种新数据类型,根据Cat类可以创建许许多多的实例。再比如:int数据类型有python提供,我们可以给出许许多多int类型的实例,比如100,200,300....

注意:1. 基本数据类型有python提供,新的数据类型有我们自己自定义。

​ 2. 创建实例对象有许多说法,如创建一个对象、实例化对象,把类实例化...

快速入门

定义一个类使用class关键字

class Cat:
    age = None,
    name = None,
    color = None

实例化对象以及修改属性名如下:

cat1 = Cat()
cat1.name = "小白"
cat1.age = 2
cat1.color = "白色"

如果要访问该对象,与修改属性名的语法相同,使用对象名.属性名,即cat1.name访问name属性

对象布尔值

Python所有对象都有一个布尔值,通过内置函数bool()可以获取对象的布尔值

  1. False、0、None、空字符串、空列表、空字典、空元组、空集合均为False
  2. 在if判断里,可以直接使用变量判断是否为True,如下操作:
content = "hello"
if content:
    print(content)
else:
    print("空字符串")

成员方法

类中定义的函数,称为成员方法

def 方法名(self, 形参列表):
    方法体
  1. 在方法定义的参数列表中,会有一个self
  2. self是定义成员方法时,需要写上的
  3. self表示当前对象本身
  4. 当我们通过对象调用方法时,self会隐式的传入
  5. 在方法内部,需要使用self,才能访问到成员变量
class Person:
    # 成员变量
    name = None
    age = None
    
    # 成员方法
    def hi(self):
        print("hi python")
        
    def cal01(self):
        result = 0
        for i in range(1, 1001):
            result += i
        print(result)
     
    def cal02(self, n):
        result = 0
        for i in range(1, n+1):
            result += i
        print(result)
     
    def get_sum(self, n1, n2):
        return n1 + n2;

除了以上这种定义成员方法的方法以外,还有一种动态绑定方法,但是只能给实例化对象动态的添加方法,如下代码:

def hi():
    print("hi python")

class Person:
    name = None
    age = None

p = Person()
p2 = Person()
# 动态的给p对象添加方法,只是给p添加方法,并不是给Person类添加方法
p.m1 = hi
p.m1()

# p2.m1()会报错,因为没有动态的给p2添加方法
p2.m1()

self详解

  1. 如果在成员方法内,想要访问对象的成员变量或者调用其他的成员方法,那就得用self
class Cat:
    name = "波斯猫"
    
    def info(self, name):
        print(f"name信息: {name}")
        print(f"属性name: {self.name}")
    
    def eat(self):
        self.info()

cat = Cat()
cat.info("小猫")
  1. 如果在成员方法内不想加self,那么就得在该方法上加上注解@staticmethod,就可以使该方法变成静态方法
  1. 静态方法不会接受隐式的第一个参数
  2. 静态方法可以不用实例化对象,直接使用类名就可以进行调用
class Dog:
    name = "藏獒"
    age = 2
    
    def info(self, name):
        print(f"name信息 -> {name}")
        
    # 静态方法
    @staticmethod
    def ok():
        print("ok()....")

dog = Dog()
dog.info("德牧")

# 通过对象调用
dog.ok()
# 对过类名调用
Dog.ok()
  1. self表示当前对象本身,也就是哪个对象调用,self就代表哪个对象
class Dog:
    name = "藏獒"
    age = 2
    
    def hi(self):
        # id为内存地址
        print(f"hi self: {id(self)}")
 
dog2 = Dog()
# 查看dog2的两个id值是否相同,如果相同,说明self就是dog2
print(f"hi self: {id(dog2)}")
dog2.hi()
  1. 当我们通过对象调用方法时,self会隐式的传入
class Dog:
    name = "藏獒"
    age = 2
    
    def hi(self):
        # id为内存地址
        print(f"hi self: {id(self)}")
 
dog2 = Dog()
# dog2在调用的时候,没有传入参数
dog2.hi() 
# 可以理解为dog2.hi(dog2)

作用域

在面向对象编程中,主要的变量就是成员变量和局部变量

  1. 局部变量,一般是指在成员方法中定义的变量
  2. 成员变量的作用域在整个类中,即该类的任何地方
  3. 局部变量的作用域只能在该成员方法中
  4. 局部变量与成员变量可以重名,带上self即表示成员变量,反之表示局部变量

构造方法

如果想要创建类的对象时,就直接指定这个对象的属性,而不是通过对象名.属性来设置的话,就得使用构造方法,基本语法如下:

def __init__(self,参数列表):
    代码...
  1. 在初始化对象时,会自动执行构造方法,只要实例化一次对象,就会执行一次
  2. 在初始化对象时,实参会自动传递给构造方法
  3. 构造方法是完成对象的初始化任务
  4. 一个类只有一个构造方法,如果写了很多个,也只有最后一个生效
  5. Python支持动态生成对象的成员属性,可以不用在类里面定义成员属性
  6. 构造方法不准有返回值
class Person:
    name = None
    age = None
    # 把接收到的name和age赋给成员变量
    def __init(self, name, age):
        self.name = name
        self.age = age
        
p1 = Person("lwpigking", 20)
class Person:
    def __init(self, name, age):
        # 把接收到的name和age赋给成员变量
        self.name = name
        self.age = age
        
p1 = Person("lwpigking", 20)

封装

封装就是把抽象出的数据【成员属性】和对数据的操作【成员方法】封装在一起,数据被保护在内部。程序只有通过被授权的操作,才能对数据进行访问。

封装的好处

  1. 可以将程序实现的细节隐藏起来,比如有一个绘制柱状图的方法,该方法的代码非常庞大,但是我们只要调用这个方法,就可以画出柱状图
  2. 可以对数据进行验证,保证合理
  3. 可以保护数据隐私,要求授权才可以访问

私有成员

通常情况下,类中的变量和方法都是共有的,名称前都没有下划线

公共的变量和方法,在类的外部、类的内部,都可以正常访问

  1. 如何将属性、方法进行私有化?

    类中的变量或方法以双下划线开头命名,则该变量或方法为私有的,私有的变量或方法,只能在本类内部使用,类的外部无法使用

  2. 如何访问私有属性和方法?

    提供公共的方法,用于私有成员的操作

class Clerk:
    # 公共的属性
    name = None
    # 私有的属性
    __job = None
    __salary = None
    
    def __init__(self, name, job, salary):
        self.name = name
        self.__job = job
        self.__salary = salary
    
    def set_job(self, job):
        self.__job = job
    def get_job(self):
        return self.__job
    
    # 私有方法
    def __hi(self):
        print("hi")
        
clerk = Clerk("tiger", "python工程师", 20000)
# 公共属性,在类的外部可以直接访问
print(clerk.name)
# 如果是私有属性,类的外部不可以直接访问
print(clerk.__job) # 这行执行不了,因为__job是私有的

继承

# 继承的基本语法
# 继承Person类
class Student(Person):
    <statement>
  1. 子类继承了所有的属性和方法,公有属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
  2. 如果子类和父类出现同名的成员,可以通过父类名、super()访问父类成员
  3. 重写又称覆盖(oevrride),即子类继承父类的属性和方法后,根据业务需要,再重新定义同名的属性或方法

多态

多态即多种状态,不同的对象调用相同的方法,表现出不同的状态,比如一个父类,有多个子类,不同的子类对象调用相同的方法,执行的时候产生不同的状态

抽象类

  1. 当父类的某些方法,需要声明,但是又不确定如何实现时

  2. 不需要实例化父类对象,父类主要的是用于设计和指定规范,让其它类来继承并实现

  3. 用@abstractmethod增加抽象方法,时该类变成抽象类

  4. 抽象类不能实例化

posted @ 2025-09-08 17:48  lwpigking  阅读(16)  评论(0)    收藏  举报