面向对象

Posted xufengnian

tags:

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

一、组合

组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象

技术图片
class Foo:
    pass


class Bar:
    pass


obj = Foo()
obj.attr = Bar()
View Code

使用组合也是为了减少代码冗余

如何使用组合

技术图片
class OldboyPeople:
    school = Oldboy

    def __init__(self,name,age,sex,):
        self.name = name
        self.age = age
        self.sex = sex

class OldboyStudent(OldboyPeople):
    def __init__(self, name, age, sex,score=0):
        OldboyPeople.__init__(self,name,age,sex)
        self.score = score
        self.courses=[]

    def choose_course(self):
        print(%s choosing course % self.name)

    def tell_all_course(self):
        print((学生[%s]选修的课程如下 %self.name).center(50,=))
        for obj in self.courses:
            obj.tell_info()
        print(=*60)

class OldboyTeacher(OldboyPeople):
    def __init__(self,name,age,sex,level):
        OldboyPeople.__init__(self,name,age,sex)
        self.level=level
        self.courses=[]

    def score(self,stu,num):
        stu.score=num

    def tell_all_course(self):
        print((老师[%s]教授的课程如下 %self.name).center(50,*))
        for obj in self.courses:
            obj.tell_info()
        print(**70)

class Course:
    def __init__(self,c_name,c_price,c_period):
        self.c_name = c_name
        self.c_price = c_price
        self.c_period = c_period

    def tell_info(self):
        print(<课程名:%s 价钱:%s 周期:%s> %(self.c_name,self.c_price,self.c_period))

# 创建课程对象
python=Course(python全栈开发,1900,5mons)
linux=Course(linux架构师,900,3mons)


stu1=OldboyStudent(刘二蛋,38,male)
stu1.courses.append(python)
stu1.courses.append(linux)
# print(stu1.courses)
stu1.tell_all_course()


tea1=OldboyTeacher(egon,18,male,10)
tea1.courses.append(python)
# print(tea1.courses)
tea1.tell_all_course()
View Code

二、多态

多态指的是同一种/类事物的不同形态

多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象

多态性的精髓:统一

多态其实是一种思想,就是在开发的时候,定义类时,都给他们写绑定方法method,虽然方法导致的结果各不相同,但是这样就可以不用考虑他们是否有绑定方法method。而是,他们一定有一个方法method,可以直接去调用它。

技术图片
class People(Animal):
    def speak(self):
        print(say hello)

    def run(self):
        pass

class Dog(Animal):
    def speak(self):
        print(汪汪汪)

    def run(self):
        pass

class Pig(Animal):
    def speak(self):
        print(哼哼哼)

    def run(self):
        pass

obj1=People()
obj2=Dog()
obj3=Pig()
View Code

三、封装

装:往容器/名称空间里存入名字

封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内

如何封装:

在类内定义的属性前加__开头

1.这种隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部访问

2.该变形操作只在类定义阶段检测语法时发生一次,类定义阶段后新增的__开头的属性并不会变形

3.如果父类不想让子类覆盖自己的属性,可以在属性前加__

技术图片
class Foo:
    __x=111 # _Foo__x
    __y=222 # _Foo__y


    def __init__(self,name,age,sex):
        self.__name=name
        self.__age=age
        self.sex=sex

    def __func(self): #_Foo__func
        print(func)

    def get_info(self):
        print(self.__name,self.__age,self.__x)

a=Foo(lqz,18,male)
print(a.__dict__)
# print(a._Foo__name)
# print(a._Foo__age)
a.get_info()
View Code

封装数据属性:将数据属性隐藏起来,类外就无法直接操作属性,需要类内开辟一个接口来外部的使用可以间接地操作属性,可以在接口内定义任意的控制逻辑,从而严格控制使用对属性的操作

技术图片
class People:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def tell_info(self):
        print(name:%s age:%s % (self.__name, self.__age))

    def set_info(self, name, age):
        if type(name) is not str:
            print(名字必须是字符,傻叉)
            return
        if type(age) is not int:
            print(年龄必须是整数,傻叉)
            return
        self.__name = name
        self.__age = age

a=People(lqz,18)
a.set_info(许三多,22)
a.tell_info()
View Code

四、property装饰器

property装饰器是用来将类内的函数属性伪装成数据属性的

技术图片
class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight/self.height**2

lqz=People(lqz,90,1.8)
print(lqz.bmi)
View Code

五、绑定方法与非绑定方法

绑定给对象的方法:类中定义的函数默认就是绑定给对象的

绑定给类的方法:为类中定义的函数加上一个装饰器classmethod。类实例化出来的对象也可以调用该方法,但是不建议这么用。

 

非绑定方法:既不与类绑定,又不与对象绑定,意味着对象和类都可以来调用,无论谁来调用都是一个普通的函数,没有自动传值的效果

技术图片
class Foo:
    def f1(self):
        print(self)

    @classmethod
    def f2(cls):
        print(cls)

    @staticmethod
    def f3(x,y):
        print(f3,x+y)
a=Foo()
Foo.f2()
a.f2()
a.f3(1,2)
Foo.f3(4,5)
View Code

六、isinstance与issubclass

判断对象是否属于哪个类isinstance

判断类是否继承哪个类issubclass

技术图片
class A:
    school = oldboy
class Bar:
    pass
class Foo(Bar):
    pass
obj = Foo()
print(issubclass(Foo,A))
print(issubclass(Foo,Bar))
print(isinstance(obj, Bar))
print(isinstance(obj, A))
View Code

七、反射

反射:通过字符串来反射/银蛇到对象/类的属性上

技术图片
class People:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def run(self):
        print(%s is running%self.name)

obj=People(egon,18)
#hasattr判断对象是否有某个属性
#delattr删除对象的某个属性
#getattr获取对象的某个属性
#setattr设置对象的某个属性
print(hasattr(obj,name))
print(getattr(obj,name))
setattr(obj,name,lwx)
print(getattr(obj,name))
print(hasattr(obj,run))
delattr(obj,name)
print(hasattr(obj,name))
View Code

 

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

面向面试编程代码片段之GC

PHP面向对象之选择工厂和更新工厂

Java中面向对象的三大特性之封装

python之路之前没搞明白4面向对象(封装)

Scala的面向对象与函数编程

Python面向对象学习之八,装饰器