Fork me on GitHub

Python学习记录5-面向对象

OOP

  • 思想

    • 以模块化思想解决工程问题
    • 面向过程 vs 面向对象
    • 由面向过程转向面向对象
  • 常用名词

    • OO:面向对象
    • ooa:分析
    • ood:设计
    • oop:编程
    • ooI:实现
    • ooa -> ood -> ooi
  • 类 vs 对象

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

    • 动作,函数
    • 属性,变量
  • is-a

  • 定义类:class关键字

  • 类命名:

    • 遵循大驼峰
    • 第一个字母大写

    #定义学生类,和几个学生
    >>> class Student():
            # 此处定义一个空类
            # pass是关键字,表示占位用的,无意义
            pass
    
    # 定义一个对象
    >>> xiaobai = Student()

    >>> class PythonStudent():
            name = "NoOne"
            age = 18
            course = "Python"
    
    #定义类中的函数,一般需要有self关键字,其余跟普通函数基本相同   
    >>> def giveMeMoney():
            print("给我钱")
            return None
    
    >>> xiaobai = PythonStudent()
    >>> print(xiaobai.name)
    >>> print(xiaobai.age)
    >>> print(xiaobai.course)

    输出:
    NoOne
    18
    Python

类的属性


    # 类的例子
    # 注意类的定义
    >>> class Student():
            name = "哈哈哈"
            age = 19
    
    >>> def sayHi(self):
            print("小乔要努力变强")
            return None

    # 实例化
    >>> zhaosi = Student()
    >>> print(zhaosi.name)
    >>> zhaosi.sayHi()

    输出:
    哈哈哈
    小乔要努力变强
    

self

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

    # self

    # 实例调用函数
    >>> class Student():
            name = "哈哈哈"
            age = 19
    
    >>> def sayHi(self):  # self不是一个关键字 只是一个形参 可以任意替换
            print("小乔要努力变强")
            return None


    >>> xiaoqiao = Student()

    # 打招呼
    >>> xiaoqiao.sayHi() #上面定义的sayHi()方法 是需要一个参数的 但是这里是默认将调用者放入了
                 #此时不能再传入参数 会报参数过多的错误

    输出:
    小乔要努力变强


类的变量作用域的问题

  • 类变量:属于类自己的变量
  • 实例变量:属于实例的变量
  • 访问实例的属性,如果实例没有定义属性,则自动访问类的属性,如果类也没有定义则报错

    >>> class Student():
        # name,age是类的变量
        # 注意类的变量的定义位置和方法
        # 不需要前缀
        name = "哈哈哈"
        age = 19
    
    >>> def sayHi(self, n, a):
            self.name = n
            self.age = a
            print("My name is {},i am {} years old".format(self.name,self.age))
            return None

    # 实例变量可以使用类的变量
    >>> hh = Student()
    >>> hh.sayHi("嘻嘻",17)
    >>> print("My name is {},i am {} years old".format(Student.name,Student.age))
    >>> print("My name is {},i am {} years old".format(hh.name,hh.age))

    输出:
    My name is 嘻嘻,i am 17 years old
    My name is 哈哈哈,i am 19 years old
    My name is 嘻嘻,i am 17 years old
    

访问类的属性

  • 在类里面如果强制访问类的属性,则需要使用_class_,(注意前后的两个下划线)
  • 类方法:
    • 定义类的方法的时候,没有self参数
    • 类的方法中只允许使用类的内容
    • 两种用法
      • ClassName
      • class ,前后各两个下划线

    >>> class Student():
        # name,age是类的变量
        # 注意类的变量的定义位置和方法
        # 不需要前缀
        name = "哈哈哈"
        age = 19
    
    >>> def sayHi(self):
            print("My name is {},i am {} years old".format(self.name,self.age))
            return None
   
    # sayHi是类方法
    # 如何访问类的变量
    # 但是调用需要用到特殊的方法
    >>> def sos():
            # 类方法中不允许访问实例的任何内容
            print("My name is {},i am {} years old".format(Student.name,__class__.age))
            return None

    # 类的方法
    >>> s = Student()
    >>> s.sayHi()
    >>> Student.sos()

    输出:
    My name is 哈哈哈,i am 19 years old
    My name is 哈哈哈,i am 19 years old

构造函数

  • 类在实例化的时候,执行一些基础性的初始化的工作
  • 使用特殊的名称和写法
  • 在实例化的时候自动执行
  • 是在实例化的时候第一个被执行的函数(此处先这样理解)
    
    # 注意类的定义
    >>> class Student():
            name = "NoName"
            age = 0
    
    # 构造函数名称固定,写法相对固定
    >>> def __init__(self):
            print("我是构造函数")
        
    >>> xiaoming = Student()
    >>> print("-------------")
    >>> print(xiaoming.name)
    >>> print(xiaoming.age)

    输出:
    我是构造函数
    -------------
    NoName
    0

面向对象的三大特征

  • 继承
  • 封装
  • 多态

继承

  • 子类可以使用父类定义的内容或者行为等
  • 继承的实现
    • 父类、基类、超类:被继承的类,Base Class,Supper 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 = "I can fly"
    >>> def flying(self):
            print("我会飞了")

    >>> class BirdMan(Person,Bird):
            pass

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

    输出:
    我会飞了
    NoName

issubclass检测是否是子类

  • 可以用来检测两个类的父子关系

    # 利用刚才定义的Bird,BirdMan,Person,Teacher检测父子关系

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

    输出:
    True
    True
    False

构造函数

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

    #此时被调用的构造函数    
    >>> b = Bird()    
    
    输出:
    我被调用了

    ---------------------------------------------------------------------------------------------------

    # 构造函数2
    >>> class Person():
            def __init__(self,name,age):
                print(name,age)
        
    >>> p = Person("哈哈哈",19) 

    输出:
    哈哈哈 19

构造函数的继承

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

    # 构造函数默认继承

    >>> class Person():
            def __init__(self, name, age):
                print("Person=({},{})".format(name, age))

    >>> class Teacher(Person):
            pass

    >>> t = Teacher("哈哈哈",19)

    # 上面的构造函数是需要两个参数的,而下面却没有给出所以会报错
    #t = Teacher() 

    输出:
    Person=(哈哈哈,19)

总结

Python和Java都是面向对象的,因此还是比较好理解的,但是Python定义的语法上还是跟Java有一些区别的,消化吸收,加油。

posted @ 2019-10-09 17:08  黄焖鸡米饭-  阅读(130)  评论(0编辑  收藏  举报