第18天 面向对象编程思想 面向对象语法 面向对象封装的特性 隐藏属性

面向对象编程与面向过程编程的差别
面向过程编程:复杂的问题简单化,扩展性差。
面向对象编程:复杂读变高,扩展性强。

面向对象编程
核心是对象二字,对象就是一个用来盛放数据与功能的容器
基于该思想编写程序就是创造一个个的容器

专门语法

对象
属性查找

面向对象的三大特性
封装:归类整合,把相关的数据跟功能封装在一起,很好的体现了扩展性强的特点
继承
多态

实例化
调用类产生对象的过程称为实例化
调用类称为类的实例化
调用类的结果是一个对象,这个对象称为类的实例

面向对象编程思想

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


student = {
     "name": "nana",
           "age": 18,
           "gender": "female",
           "tell_info": tell_info}    #学生对象,学生容器,self自己调自己的功能

student["tell_info"](student)

案例2:
类:用来存放相似数据,已经相似功能的容器,用来节省内存空间
def tell_info(aaa):
    print("my name is %s, my age is %s,my gender is %s" % (student["name"], student["age"], student["gender"]))

student = {
     
    "school": "清华大学",
    "name": "nana",
    "age": 18,
    "gender": "female",
    "tell_info": tell_info}  # 学生对象,学生容器,self自己调自己的功能

student["tell_info"](student)

student1 = {
     
    "school": "清华大学",
    "name": "dada",
    "age": 19,
    "gender": "male",
    "tell_info": tell_info}  # 学生对象,学生容器,self自己调自己的功能

student["tell_info"](student1)

类与对象的关系图
类有两种属性:数据属性和函数属性

  1. 类的数据属性是所有对象共享的

  2. 类的函数属性是绑定给对象用的
    第18天 面向对象编程思想 面向对象语法 面向对象封装的特性 隐藏属性_第1张图片
    在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类…最后都找不到就抛出异常

类与对象原理
定义类发生的事情
类与对象本质上都是名称空间,对象里面盛放字典独有类型的元素,类里面盛放相同类型的元素
类与函数的定义的差别,函数的名称空间只有在调用的时候才产生名称空间,类只要定义就会运行代码产生名称空间
类名:采用驼峰体

类与对象
对象是盛放相关的数据与功能的容器
类存放的是对象相似的数据与功能的容器

class Student:
    school = "清华大学"

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

    print("=====")

# print(Student.__dict__)     #class就是在背后把Student的同类型元素做成了一个字典的模式,__dict__表示查看类里面的名称空间的元素

#调用类的底层逻辑
# 创造一个对象的字典格式,用来存放对象独有的数据
# 将对象与类建立好关联
obj1 = Student()
# print(obj1.__dict__)  #建了一个空字典
# obj1.name = "nana"  # obj1.__dict__["name"] = "nana"
# obj1.age = 18  # obj1.__dict__["age"] = 18
# obj1.gender = "female"  # obj1.__dict__["gender"] = "female"
#
obj2 = Student()
# obj2.name = "dada"  # obj2.__dict__["name"] = "dada"
# obj2.age = 19  # obj2.__dict__["age"] = 19
# obj2.gender = "male"  # obj2.__dict__["gender"] = "male"

# 把对象写成函数
def init(self, x, y, z):
    self.name = x
    self.age = y
    self.gender = z


init(obj1, "nana", 18, "female")
init(obj2, "dada", 19, "male")

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

调用类的过程

class Student:
    school = "清华大学"

    def __init__(self, x, y, z):         #Student.__init__(空对象,"nana", 18, "male")
        self.name = x      # 空对象.name="nana"
        self.age = y       # 空对象.age=18
        self.gender = z    # 空对象.gender="female"

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


调用类的过程
1.先创造一个空对象
2.自动触发类内的__init__函数的运行,将空对象当作第一个参数自动传入
3.返回一个初始化好的对象给obj1  #注意,obj1返回值是Student()的返回值,__init__规定不能有返回值
obj1 = Student("nana", 18, "female")  # 返回值obj1={
     "name"="nana","age"=18,"gender"="female"}
obj2 = Student("dada", 19, "male")

属性查找

对象.属性的查找顺序,优先从对象里面找,如果找不到会再从类里面找
# class Student:
#     school = "清华大学"
#
#     def __init__(self, x, y, z):
#         self.name = x
#         self.age = y
#         self.gender = z
#
#     def tell_info(student):
#         print("my name is %s, my age is %s,my gender is %s" % (student.gender, student.age, student.gender))
#
#
# obj1 = Student("nana", 18, "female")
# obj2 = Student("dada", 19, "male")
#
# Student.tell_info(obj1)
# Student.tell_info(obj2)

# print(obj1.name)  # obj1.__dict__["name"]
# print(obj1.school)

# 类.属性,从类自己的字典里面找,类内部传参,无法去全局名称空间里面找值,只能再类内部找,类内部找不到就报错
# print(Student.school)    # 显示类里面school的值
# print(Student.__init__)  # 函数Student.__init__的内存地址
# print(Student.tell_info)  # 函数tell_info的内存地址

# 类中的数据属性是直接共享给所有对象用的
# 如果类的数据属性变了,那就所有数据的属性都改变,如果对象的数据属性改变了,那么只在该数据只在该对象内部发生改变
# obj1.school = "xxx"
# print(Student.school)  # 清华大学
# print(obj2.school)  # 清华大学
# print(obj1.school)  # xxx

类中的函数属性
类中的函数可以直接调用,如果类来调用那么就是一个普通函数,按照函数的使用规则去使用就可以
但其实类中的函数时给对象用的,如果对象来调用那就是一个绑定方法,绑定方法会将调用者当作第一个参数传入

class Student:
    school = "清华大学"

    def __init__(self, x, y, z):
        self.name = x
        self.age = y
        self.gender = z

    def tell_info(student):
        print("my name is %s, my age is %s,my gender is %s" % (student.gender, student.age, student.gender))


obj1 = Student("nana", 18, "female")
obj2 = Student("dada", 19, "male")

Student.tell_info(obj1)
Student.tell_info(obj2)
print(obj1.tell_info)   #<bound method Student.tell_info of <__main__.Student object at 0x00EAE6D0>>
绑定方法的概念
类中定义的函数一般都至少需要一个参数的,该参数是往定义的函数里面自动传入对象的,这种绑定关系就是绑定方法
obj1.tell_info()    #tell_info()会将调用者当作第一个参数传入,如果函数中还有其他参数,那么继续传其他的参数
obj2.tell_info()


隐藏属性
__开头的属性的特点:
并没有真的藏起来,只是变形的
**该变形只在类定义阶段,扫描语法的时候执行,此后__开头的属性都不会变形
该隐藏对外不对内

class People:
#     __country = "China"  # 将一个属性加了__开头就代表把该属性隐藏了
    def __init__(self, name, age):
        self.__name = name  # {
     '_People__name': 'nana'}
        self.__age = age  # '_People__age': 18

    def __func(self):  # _People__func
        print("xx")

    def tell_name(self):
        print(self.__name)  # {
     '_People__name': 'nana'}
        # self["__name"]

obj1 = People("nana", 18)
obj1.tell_name()

print(People.__country)    #加了__显示没有该属性
print(People.__dict__)     #__country显示结果:'_People__country': 'China'
print(People._People__country)
print(obj1.__dict__)

obj1.__gender = "female"
print(obj1.__gender)  # 可以直接访问到,female
obj1.tell_name()  # 对外不对内

为何要影藏属性

1.隐藏数据属性为了严格控制类外部访问者对属性的操作
class People:
    def __init__(self, name, age):
        self.__name = name  # _People__name
        self.__age = age  # _People__age

    def tell_info(self):				#通过改接口的方式让用户只能查看
        print(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("nana", 18)
# obj1.tell_info()         
obj1.set_info("NANA", 18)
obj1.tell_info()

2.隐藏函数(功能)属性为了隔离复杂度
class ATM:
    def __card(self):
        print("插卡")
    def __auth(self):
        print("用户认证")
    def __input(self):
        print("取出")

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()

a = ATM()
a.withdraw()

你可能感兴趣的:(python)