Python学习笔记 四:面向对象程序设计(OOP)

1.OOP(Object Oriented Programming)

  • 思想:

    • 以模块化思想解决工程问题
    • 面向过程 vs 面向对象
    • 由面向过程转向面向对象
    • 例子,我要开一个学校:
      • 讲师
      • 班主任
      • 学生
      • 教室
      • 。。。。。。
  • 常用名词

    • OO:面向对象
    • OOA:分析
    • OOD:设计
    • OOP:编程
    • OOI:实现
    • OOA -> OOD -> OOI
  • 类 vs 对象 (两者是归属关系,但是不是组成关系)

    • 类:抽象,描述的是一个集合,侧重于共性(学生类)
    • 对象:具象,描述的是个体(张同学)
  • 类的内容:

    • 动作,函数
    • 属性,变量
  • 定义类:class关键字

  • 类命名:

    • 遵循大驼峰(每一个单词的首字母都采用大写字母)
    • 第一个字母大写
# 定义学生类,和几个学生

class Student():
    # 此处定义一个空类
    # pass是关键字,表示占位用的,无意义(养成好习惯)
    pass
# 定义一个对象
zhangsan = Student()
# 定义时,全体缩进
class PythonStudent():
    name = "Nobody"
    age = 20
    course = "Python"
    '''
    定义类中的函数,一般要有self关键字
    其余跟普通函数基本相同
    
    '''
    
    def giveMoney(self):
        print("show me the money")
        return None
    
lisi = PythonStudent()
print(lisi.name)
print(lisi.age)
print(lisi.course)

Nobody
20
Python

2.类的属性

# 类的例子
# 注意类的定义
class Student():
    # name,age是类的变量
    name = "amy"
    age = 20
    
    def sayHi(self):
        print("类的属性")
        return None
    
    
    def sayHello(koko):
        print("将self替换为koko")
        return None 
# 实例化
lisi = Student()

print(lisi)

2.1 self

  • self可以用别的名称代替
  • self不是关键字
  • 作用是指代本身
# self举例

# 实例调用函

honghong = Student() # 实例化yaoyao

# 让honghong跟我打招呼
# honghong调用sayHi没有输入参数
# 因为迷人实例作为第一个传入的参数,即honghong代替self
honghong.sayHi()

# 错误的案例:
# a = "你好"
# honghong.sayHi(a)

类的属性

#这个案例说明self的名称可以更改,实际上self为形参
honghong.sayHello()

将self替换为koko

2.2 类的变量作用域的问题

  • 类变量:属于类自己的变量
  • 实例变量:属于实例的变量
  • 以下两个案例的总结:
    • 定义了实例的属性后,当访问实例的属性时,优先访问实例自己的属性;若没有,则访问类的属性。
# 案例1:

# 注意类的定义
class Student():
    
    # name,age是类的变量
    name = "amy_77"
    age = 20
    
    def sayHi(self):
        print("My Name is {}, i am {} years old".format(self.name,self.age))
        self.age = 21
        self.name = "NoName"
        return None

# 此案例说明,实例变量可以借用类的变量
qianqian = Student()
qianqian.sayHi()

My Name is amy_77, i am 20 years old

# 案例2:

# 注意类的定义
class Student2():
    
    # name,age是类的变量
    name = "amy_77"
    age = 20
    
    def sayHi(self, n, a ):  # 实例变量,给self定义自己的变量name和age
        self.name = n
        self.age = a
        
        print("My Name is {}, i am {} years old".format(self.name,self.age))
        return None

# 此案例说明,实例变量可以借用类的变量
qianqian = Student2()

# 注意观察下面语句打开和关闭后的区别
# qianqian.sayHi("yuanyuan", 30)

print("My Name is {}, i am {} years old".format(Student2.name,Student2.age))
print("My Name is {}, i am {} years old".format(yuanyuan.name,yuanyuan.age))

#若果访问实例的属性没有定义,则自动访问类的属性
# 如果类也没有定义,则报错

My Name is amy_77, i am 20 years old
My Name is amy_77, i am 20 years old

2.3 访问类的属性

  • 在类里面如果强制访问类的属性,则需要使用__class__(前后两个下划线)
  • 类方法:
    • 定义类的方法的时候,没有self参数
    • 类的方法中只允许使用类的内容
    • 两种方法
      • ClassName
      • __ class __(前后两个下划线)
class Student3():
    
    # name,age是类的变量
    name = "amy_77"
    age = 20
    
    def sayHi(self):
        print("My Name is {}, i am {} years old".format(self.name,self.age))
        return None
    
    
    # SOS是类的方法
    def SOS():
        # 类方法中不允许访问实例的任何内容
        #print("My Name is {}, i am {} years old".format(self.name,self.age))
        
        # 如果访问想要类的内容,有下面两种方法:
        print("My Name is {}, i am {} years old".format(Student3.name,__class__.age))
        return None
    
# 体验类的方法
s = Student3()
s.sayHi()

# 调用类方法的例子
Student3.SOS()
# SOS() takes 0 positional arguments but 1 was given
# SOS()接受0个位置参数,但给出了1个

My Name is amy_77, i am 20 years old
My Name is amy_77, i am 20 years old

2.4 构造函数

  • 类在实例化的时候,执行一些基础性的初始化的工作
  • 使用特殊的名称和写法
    • 在实例化的时候自动执行
    • 是在实例化的时候 “第一个” 被执行的函数
class Student4():
    name = "Everybody"
    age = 0
    
    # 构造函数名称固定,写法相对固定
    def __init__(self):
        print("我是一个构造函数")


qianqian = Student4()
print("*******************")
print(qianqian.name)
print(qianqian.age)

我是一个构造函数


Everybody
0

3.面向对象的三大特征

  • 继承
  • 封装
  • 多态

3.1 继承(Python不重复造轮子)

  • 字类可以使用父类定义的内容或者行为等
  • 继承的实现:
    • 父类,基类,超类:被继承的类,Base Class,Super Class

    • 子类,有继承行为的类

    • 所有类都必须有一个父类

    • 如果没有,则默认是object的字类

# 所有类必须有父类
# 默认为object
class Person1():
    pass

class Person2(object):
    pass

class Person():
    name = "NoName"
    age = 0
    
# 父类写在类定义的时候的括号里
class Teacher(Person):
    pass

t = Teacher()
print(t.name)
    

NoName

class Bird():
    fly = "Yes,I can"
    
    def flying(self):
        print("飞呀飞呀")
        
class BirdMan(Person, Bird):
    pass

bm = BirdMan()
bm.flying()
print(bm.name

飞呀飞呀
NoName

3.2 issubclass检测是否是子类

  • 可以用来检测两个类的父子关系
# 利用刚才定义的Bird,BirdMan,Person,Teacher,检测父子关系

print(issubclass(BirdMan, Bird))
print(issubclass(BirdMan, Person))
print(issubclass(BirdMan, Teacher))

# help(issubclass)

True
False
False

4.构造函数

  • 在函数实例化的时候调用的一个函数
  • 自动调用
  • 要求:
    • 第一个参数必须有,一般推荐为self
  • 构造函数的调用时间:一般认为在实例化的时候,第一次被调用
  • 一般不手动调用,实例化的时候自动调用,参数需要写入类名称后面的括号中
class Bird():
    def __init__(self):
        print("我被调用了")
        return None
    
# 此时被调用构造函数
b = Bird()

我被调用了

# 构造函数2

class Person():
    def __init__(self, name, age):
        print(name, age)
        
p = Person("amy", 21)

amy 21

4.1 构造函数的继承

  • 构造函数默认继承
  • 一旦子类定义了构造函数,则不再自动调用父类构造函数
# 构造函数默认继承

class Person():
    def __init__(self, name, age):
        print("Person = ({}, {})".format(name, age))
        
        
# Teacher自动继承上面的构造函数
class Teacher(Person):
    pass

t = Teacher("amy", 21)

t = Teacher()# 此代码报错

Person = (amy, 21)

猜你喜欢

转载自blog.csdn.net/amyniez/article/details/104363590