欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

日知录(五):python面对对象编程

程序员文章站 2022-03-04 08:53:08
OOP理解OOP的想法终于到这个part了,如何面对对象编程呢?来一个高大上的定义:面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。之前学的是C语言,是一种面向过程的程序设计思想。1.在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。2.类(Class)和实例(Instance)的概念Class...

OOP

理解OOP的想法

终于到这个part了,如何面对对象编程呢?
来一个高大上的定义:面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
之前学的是C语言,是一种面向过程的程序设计思想。
1.在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
2.类(Class)和实例(Instance)的概念
Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student。
3.面向对象的设计思想是抽象出Class,根据Class创建Instance。
4.我大白话讲讲:简单点理解,动物分类:界门纲目科属种,比如狼这一实例属于犬科,犬科的基本特点,在_init_内定义(数据封装)。狼在继承犬科(继承)这一基本特点后,还有一些自己的特点,或者可以重新定义一些基本特点(多态性)。同时,犬科与猫科之间,必定是由一些特点是根本性的,不能改变的。(即 该类的私有属性)

接下来看看我们对象的特性

特点一:数据封装

# -*- coding: UTF-8 -*-
 #创建一个新的抽象类:用class语句,Student为类的名称
class Student(object):                     
#__init__()是一种特殊的方法,被称为类的构造函数或初始化方法
    def __init__(self,name,score):          
        self.name=name   					
        self.score=score
#slef代表类的实例,self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

    def print_score(self):
        print('%s:%s' % (self.name,self.score))

#创建类的实例对象bart,并通过__init__方法接收参数
bart = Student('Bart Simpson', 5)
#访问对象的属性.print_score()
bart.print_score()

该例中定义了print_score()方法,即在Student类的内部定义访问数据的函数print_score(),这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法。

定义方法时进行数据封装

1.定义一些特殊方法

一般是系统定义名字,类似__init()__之类的

  1. __foo __(): 定义的是特殊方法,一般是系统定义名字 ,类似 __ init __() 之类的。
  2. _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

2.定义类的私有属性

__private_attrs: 两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

3.定义类的方法

def 关键字:在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数

4.定义类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods
试图从外部访问私有变量时的报错

# -*- coding: UTF-8 -*-

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0  # 公开变量

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print(self.__secretCount)


counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)
print(counter.__secretCount ) 
# 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'

Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性

# -*- coding: UTF-8 -*-

class Runoob:
    __site = "www.runoob.com"

runoob = Runoob()
print (runoob._Runoob__site)

结果

www.runoob.com

特点二:继承

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)

1.继承1个类

class 派生类名(基类名)
···

2.继承多个类

class A:        # 定义类 A
.....

class B:         # 定义类 B
.....

class C(A, B):   # 继承类 A 和 B
.....

3.方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法

class Animal(object):
    def run(self):
        print('Animal is running...')

class Dog(Animal):
    def run(self):
        print('Dog is running...')

    def eat(self):
        print('Eating meat...')

class Cat(Animal):
    def run(self):
        print('Cat is running...')

dog = Dog()
dog.run()

cat = Cat()
cat.run()

运行结果

Dog is running...
Cat is running...

当子类和父类都存在相同的run()方法时,调用时子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态

特点三:多态性

多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可,牵一发而动全身的感觉,就是从父类更改就可以。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态。

获取对象信息

在引用对象时,了解对象的类型和方法

1. type()

日知录(五):python面对对象编程

2. isinstance()

要判断class的类型,可以使用isinstance()函数

3. dir()

要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。
配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态
日知录(五):python面对对象编程
日知录(五):python面对对象编程
日知录(五):python面对对象编程

类属性与实例属性

实例绑定属性的方法是通过实例变量,或者通过self变量

class Student(object):
    def __init__(self, name):
        self.name = name

s = Student('Bob')
s.score = 90

以下摘自廖雪峰老师的教程实例。
当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。来测试一下:

>>>class Student(object):
	name = 'Student'

>>>s = Student() # 创建实例s
>>>rint(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student

>>>print(Student.name) # 打印类的name属性
Student

>>>s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael

>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student

>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student

在编写程序的时候,不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

本文地址:https://blog.csdn.net/weixin_43883903/article/details/107175514