面向对象编程1

面向对象编程

1)、什么是面向对象?

面向对象核心是对象二字,对象就是一个用来盛放数据与功能的容器

2)、面向对象编程与面向过程编程的关系

面向过程的特点是复杂代码流程化简单化但是拓展性比较差

而面向对象编程的特点刚好与之相反,面向对象编程的特点是拓展性比较强但是编程的复杂度提高

3)、 类 与对象

类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一些列对象相似的特征与技能的结合体。

在现实世界中:先有对比双方比较 再有共同相似的概念

即先有对象再有类

在程序中:先定义类,后产生对象

在函数使用中,是先定义,后调用,类也是一样的,在程序中需要先定义类,后调用类。不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象。

引入:
同一个班级两个同学的信息  可以发现除了个人信息不同  有相同的地方


def tell_info(student):
    print('my country is %s my name is %s my age is %s my gender is %s'%(student['country'],student['name'],student['age'],student['gender']))
student={
    'country':'China',
    'name':'egon',
    'age':18,
    'gender':'male',
    'tell_info':tell_info
}
student['tell_info'](student)

def tell_info(student):
    print('my country is %s my name is %s my age is %s my gender is %s'%(student['country'],student['name'],student['age'],student['gender']))
student={
    'country':'China',
    'name':'tom',
    'age':19,
    'gender':'female',
    'tell_info':tell_info
}
student['tell_info'](student)

my country is China my name is egon my age is 18 my gender is male
my country is China my name is tom my age is 19 my gender is female


# 因此这两个代码有很多重复的地方  这里就可以用到面向对象的概念
# 可以把相同的  共用的数据和功能放到类里面 

3.1)、类的创建

定义类发生的事情
1、立即运行类体代码
2、将运行过程产生的名字都丢到类的名称空间中
class Student:          #类名 驼峰体
    country = 'China'

    def tell_info(student):
        print('my country is %s my name is %s my age is %s my gender is %s'%(student['country'],student['name'],student['age'],student['gender']))

 	print('======>')
print(Student.__dict__)
    
>>> ======>
>>>{'__module__': '__main__', 'country': 'China', 'tell_info': <function Student.tell_info at 0x000001B3401A7CA0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}


​ 3.2)、类的调用

1.0)调用类发生的事情
1、创造一个对象的字典,用来存放对象独有的数据
2、将对象与类建立好关联


obj1 = Student()
obj1.name = 'egon'  #obj1.__dict__['name'] = 'egon'
obj1.age = 18   # obj1.__dict__['age'] = 18
obj1.gender = 'male'    # obj1.__dict__['gender'] = 'male'


obj2 = Student()
obj2.name = 'william'
obj2.age = 19
obj2.gender = 'female'


print(obj1.__dict__)
print(obj2.__dict__)
print(Student.__dict__)
>>>{'name': 'egon', 'age': 18, 'gender': 'male'}
>>>{'name': 'william', 'age': 19, 'gender': 'female'}
>>>{'__module__': '__main__', 'country': 'China', 'tell_info': <function Student.tell_info at 0x0000024B6FA09700>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}


# 上面的代码可以写成函数 传入参数的形式
obj1 = Student()
obj2 = Student()

def init(self,x,y,z):
    self.name = x  # obj1.__dict__['name'] = 'egon'
    self.age = y  # obj1.__dict__['age'] = 18
    self.gender = z  # obj1.__dict__['gender'] = 'male'

init(obj1,'egon',18,'male')
init(obj2,'tom',19,'female')

print(obj1.__dict__)
print(obj2.__dict__)

print(Student.__dict__)

>>>{'name': 'egon', 'age': 18, 'gender': 'male'}
>>>{'name': 'tom', 'age': 19, 'gender': 'female'}
>>>{'__module__': '__main__', 'country': 'China', 'tell_info': <function Student.tell_info at 0x000002B308DF9700>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}



对比发现其实在一系列优化中,都是把相似的类 放到类里面 类的目的就是对象

在这个案例中除了个人信息不同 其他都相同

class Student:          #类名 驼峰体
    country = 'China'
    def __init__(self,x,y,z):
        self.name = x  # 空对象.name= 'egon'
        self.age = y  # 空对象.age = 18
        self.gender = z  # 空对象.gender = 'male'
    
    def tell_info(student):
        print('my name is %s my age is %s my gender is %s '%(student['country'],student['name'],student['age'],student['gender']))
        
 

2.0) #重新定义调用类的过程
1、先创造一个空对象
2、自动触发类内的__init__函数的运行,将空对象当作第一个参数自动传入
3、返回一个初始化好的对象  给obj1

obj1 = Student('egon',18,'male')
obj2 = Student('tom',19,'female')




# 功能实现展示👇


class Student:          #类名 驼峰体
    country = 'China'
    def __init__(self,x,y,z):
        self.name = x  # 空对象.name= 'egon'
        self.age = y  # 空对象.age = 18
        self.gender = z  # 空对象.gender = 'male'
    
    def tell_info(student):
        print('my name is %s my age is %s my gender is %s '%(student['country'],student['name'],student['age'],student['gender']))

obj1 = Student('egon',18,'male')
obj2 = Student('tom',19,'female')

obj1.tell_info()
obj2.tell_info()

>>>my country is China my name is egon my age is 18 my gender is male 
>>>my country is China my name is tom my age is 19 my gender is female

4)、属性查找

4.1) 对象.属性的查找顺序 :先从对象的字典里找,再从类的字典里找

print(obj1.__dict__)
print(obj1.tell_info)
print(obj1.country)

obj1.country='xxx'  #在对象内先重新定义了
print(obj1.country)  #所以得到的是 xxx  而不是China

{'name': 'egon', 'age': 18, 'gender': 'male'}
<bound method Student.tell_info of <__main__.Student object at 0x0000020E12054610>>
China
xxx

4.2) 类.属性的查找:从类自己的字典找

print(Student.country)
print(Student.tell_info)

China
<function Student.tell_info at 0x00000293D5A19700>

4.3)类的数据属性是直接共享给所有对象用的

Student.country='xxxx'   #类中的数据属性
obj1.country='yyyyy'  #对象中的数据属性
print(Student.country,id(Student.country))
print(obj1.country,id(Student.country))
print(obj2.country,id(Student.country))

4.4)类中的函数 类可以用,如果类来调用就是一个普通函数,该怎么传参就怎么传参

但其实类中的函数时给对象用的,对象来调用就是一个绑定方法,绑定方法的特点是会将调用者当作第一个参数自动传入

print(Student.tell_info)
Student.tell_info(obj1)
Student.tell_info(obj2)

print(obj1.tell_info)
#将调用者自动传入
obj1.tell_info()
obj2.tell_info()

》》》<function Student.tell_info at 0x000001F1CC209700>
》》》my country is China my name is egon my age is 18 my gender is male 
》》》my country is China my name is tom my age is 19 my gender is female 
》》》<bound method Student.tell_info of <__main__.Student object at 0x000001F1CBFA4610>>
》》》my country is China my name is egon my age is 18 my gender is male 
》》》my country is China my name is tom my age is 19 my gender is female 

5)、隐藏属性

class People:

    __contry = "China"  # _People__country = 'china'
    def __init__(self,name,age):
        self.__name = name  # self._People__name = name
        self.__age = age  # self._People__age  =  18

    def tell_name(self):
        print(self.__name)  # sef._People.__name
        
# print(People.__contry)
# print(People._People__contry)
# print(People.__dict__)


obj1 = People('egon',18)

print(obj1.__dict__)
# __开头的属性的特点:
1、并没有针对藏起来,只是变形的
2、该变形值在类定义阶段、扫描语法的时候执行,此后__开头的属性都不会变形
# obj1.__gender = 'male'
# print(obj1.__dict__)
# print(obj1.__gender)
3、该隐藏对外不对内
# obj1.tell_name()

#为何要隐藏属性
1、隐藏数据属性为了阳哥控制类外部访问者对属性的操作
class People:

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

    def tell_info(self):
        print("<%s:%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

obj1 = People("egon",18)

# obj1.tell_info()
# obj1.set_info("tom",28)
# obj1.tell_info()

obj1.set_info(123123123123,28)
obj1.tell_info()

2、隐藏函数属性为了隔离复杂度
posted @ 2021-01-08 18:30  williamgess  阅读(59)  评论(0编辑  收藏  举报