面向对象基础

Posted michealjy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象基础相关的知识,希望对你有一定的参考价值。

面向对象基础

继承

如何使用继承

? class 类名(父类1,父类2):

? pass

本质

? 是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中

父类/基类

子类/派生类

新式类

? 只要继承了object类,就是新式类,在python3中,默认继承object类

? python2中,需要显示的指定继承object

经典类

? 没有继承object的类,就是经典类

? python3中没有经典类

继承重用父类

方法一:指名道姓(跟继承没有关系)

class A:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.course = None

class B(A):
    #没有自己的__init__,直接继承A的
    def create_course(self, course_name):
        self.course = course_name
class C(A):
    #C有自己的__init__,需要声明A的__init__才能使用A的
    def __init__(self, name, age, gender):
        A.__init__(self, name, age): #指名道姓A使用它的__init__方法
            self.gender = gender #派生
            
        

方法二:super关键字

  1. 严格以继承属性查找关系(.mro列表中的顺序)
  2. super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性(按照继承的关系)
  3. super的完整用法是super(自己的类名,self), python3中可以简写

  4. **super.__init__()不用为self传值**

class A;
    def __init__(self, name, age):
        self.name = name
        self.age = age
     def t(self)
        print('这是A的t方法')
class B(A):
    def __init__(self, name, age, sex):
        #super(B,self).(name, age)#完整的写法,在python2中会用到,python3中按下面的写
        super().__init__(name, age) # 直接继承了父类的两个属性,必须要写两个
        self.sex = sex
    def t(self):
        #A.t(self)#和下面的语句具有相同的意思
        super().t # 调用该方法打印出 这是A的t方法

组合

通俗来讲,我有一个黑色书包,那么我是人类的对象,黑色书包是书包类的对象,则“我有黑色书包这句话就是组合:即一个对象的属性是另一个对象”

class Person:
    def __init__(self, bag):
        self.bag = bag

class Bag:
    def __init__(self, pencil, pen):
        self.pencil = pencil
        self.pen = pen

p = Person('nike')
b = Bag('pencil', 'pen')
p.b = b
print(p.b.pencil) #pencil  相当于b对象
print(p.b)#<__main__.Bag object at 0x0000017299CDD518>#打印b对象的内存地址
print(p.bag)#打印书包的名称 nike

多态和多态性

多态: 一类事物的多种形态

例如:动物类有猪,狗,人

多态性: 不考虑实例类型的情况下使用实例,比如‘讲话’这个属性,可以有‘人讲话’、‘猪讲话’、‘狗讲话’

注意python中崇尚鸭子类型:即不会强制执行,看起来、叫声、走路像鸭子就是鸭子,就是在每个派生类里面写相同名字的方法

方式一:

用abc实现接口统一化,约束代码(用的比较少)

import abc
#第一在括号中写metaclass=abc.ABCMeta
class Animal(metaclass=abc.ABCMeta):
    #第二在要约束的方法上,写abc.abstractmethod装饰器
    @abc.abstractmethod
    def speak(self):
        pass
    
class Pig(Animal):
    def speak(self):
        print('哼哼哼')
class Dog(Animak):
    def aa(self):
        print('旺旺旺')

pig = Pig()
pig.speak() #正常打印
dog = Dog()     
dog.aa()# 会报错

方式二:

用异常处理来实现(常用)

class Animal():
    def speak(self):
        #主动抛出异常
        raise Exception('你得给我重写它啊')
class Pig(Animal):
    def speak(self):
        print('哼哼哼')
class People(Animal):
    def speak(self):
        print('say hello')

pe=People()
pe.speak() # say hello


class Animal():
    def speak(self):
        #主动抛出异常
        raise Exception('你得给我重写它啊')
class Pig(Animal):
    def spk(self):
        print('哼哼哼')
class People(Animal):
    def sak(self):
        print('say hello')

pe=People()
pe.speak() # Exception: 你得给我重写它啊
   

方式三:

最常用(约定俗成写一样的方法名)

#都写speak方法
class Pig:
    def speak(self):
        print('哼哼哼')
class People:
    def speak(self):
        print('say hello')

封装

就是汉语封装,把所有东西装在一个容器内,隐藏起来

1. 隐藏属性(为了安全)

class Person:
    def __init__(self,name,age):
        self.__name=name #__变量名来隐藏
        self.__age=age
    def get_name(self):
        # print(self.__name)
        return '[----%s-----]'%self.__name

p=Person('nick',89)
print(p.age) #报错 AttributeError: 'Person' object has no attribute 'age'

print(p._Person__name)# 可以访问 或者通过p.__dict__取出值

2.隐藏方法(隔离复杂度)

class Person:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age
    def __speak(self):
        print('6666')
p=Person('nick',89)
p.__speak() #报错 AttributeError: 'Person' object has no attribute '__speak'
print(Person.__dict__)
p._Person__speak() # 用对象的字典可以拿出来

property装饰器:把方法包装成数据属性

#property装饰器:把方法包装成数据属性
class Person:
    def __init__(self,name,height,weight):
        self.name=name
        self.height=height
        self.weight=weight
    @property
    def bmi(self):
        return self.weight/(self.height**2)
        # return self.weight/(self.height*self.height)
p=Person('lqz',1.82,70)
# # print(p.bmi())
print(p.bmi) #bmi直接返回数值 21.132713440405748

property之setter

class Person:
    def __init__(self,name,height,weight):
        self.__name=name
        self.__height=height
        self.__weight=weight
    @property
    def name(self):
        return '[我的名字是:%s]'%self.__name
    #用property装饰的方法名.setter #可以限制属性的修改,规定标准
    @name.setter
    def name(self,new_name):
        # if not isinstance(new_name,str):
        if type(new_name) is not str:
            raise Exception('改不了')
        if new_name.startswith('sb'):
            raise Exception('不能以sb开头')
        self.__name=new_name

    # 用property装饰的方法名.deleter
    @name.deleter
    def name(self):
        # raise Exception('不能删')
        print('删除成功')
        # del self.__name

p=Person('lqz',1.82,70)
p.name=123
print(p.name) #Exception: 改不了

类的绑定方法

绑定给类的,类来调,会把类自身传过去

一般用在不需要通过对象,只需要通过类就能获得一些东西,可以由对象调用,但不建议

class Person:
    def __init__(self,name,age):
        print(self)
        self.name=name
        self.age=age
    @classmethod
    def test(cls):
        print(cls)
        print('类的绑定方法')
        #类实例化产生对象,返回
        return cls('lqz',19)
per1=Person.test()
print(per1) #打印的是: 类的绑定方法

类的非绑定方法

staticmethod 非绑定方法,定义在类内部,普通方法,谁都不绑定对象/类都可以调用,但是不会自动传值

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def object_method(self):
        print('我是对象绑定方法,对象来调用我')

    @classmethod
    def class_method(cls):
        print('我是类的绑定方法,类来调用我')

    #当成一个普通函数,只不过是写在类内部的
    @staticmethod
    def static_method():
        print('我是静态方法,谁都不绑定')
        
#静态方法(非绑定方法)
#类来调用
Person.static_method() #我是静态方法,谁都不绑定
# 对象来调用
p=Person('nick',19)
p.static_method() #我是静态方法,谁都不绑定

静态方法(非绑定方法)的作用跟类和对象都没有关系的时候,可以定义成静态方法,一般在类内部使用,类外部也可以使用就是一个普通函数,想把它拿到类中管理,就可以定义成静态方法

class Person:
    def __init__(self,name, age):
        self.id=self.get_uuid()
        self.name = name
        self.age = age

    #当成一个普通函数,只不过是写在类内部的
    @staticmethod
    def static_method():
        print('我是静态方法,谁都不绑定')
    @staticmethod
    def get_uuid():
        import uuid
        return uuid.uuid4()
    
p=Person('nick',19)
print(Person.get_uuid()) # 15ee76bf-930d-4297-87ba-036771e3e3de

以上是关于面向对象基础的主要内容,如果未能解决你的问题,请参考以下文章

第二十五节:Java语言基础-面向对象基础

Java基础---面向对象

面向对象基础一

面向对象基础

Python之面向对象:面向对象基础

Java基础之面向对象