面向对象2

回顾类的创建

class p1():      #定义类

    pass

 

class p2():

    pass

 

p1=p1()#实例化

p2=p2()#实例化

 

print(p1)

print(p2).

 

实例变量:在所有类的所有方法,都可以访问到

局部变量:在函数里面有效,出了函数就不可以使用。

"""

类:

可以把数据封装在类的实例里面去管理,

使用类里面的实例方法来管理这些数据,保证数据的安全性

 

类里面要有数据,还有操作数据的方法(设定操作数据的规则)

"""

person = [["wulaoshi",10],["lilaoshi",20]]

person[1][1] = -10

print(person)

 

结果显示:

D:\>py b.py

[['wulaoshi', 10], ['lilaoshi', -10]]

结果很容易被改而形成脏数据,无意中更改后就没有办法使用

 

根据类中方法set_age方法校验传参

class Person:

    def __init__(self,name,age):

        if isinstance(age,int) and age > 0:

            self.age = age

        else:

            self.age = 0

        self.name = name

   

    def set_age(self,age):

        if isinstance(age,int) and age > 0:      #根据传参判断是否符合要求;

            self.age = age

 

    def get_age(self):

        return self.age

 

p1=Person("wulaoshi",18)  #实例化

p2=Person("lilaoshi",28)      #实例化

print(p1.age)

print(p2.age)

p1.set_age(-1)             #通过访问set_age方法进行修改参数;

print(p1.age)

 

结果输出

D:\>py b.py

18

28

18                 #不符合set_age规则,没有修改成功;

 

根据私有变量self.__age防止传入外部传入脏数据

class Person:

    def __init__(self,name,age):

        if isinstance(age,int) and age > 0:

            self.__age = age           #self.__age私有变量

        else:

            self.__age = 0              #self.__age私有变量

        self.name = name

   

    def set_age(self,age):

        if isinstance(age,int) and age > 0:

            self.__age = age           #self.__age私有变量

 

    def get_age(self):

        return self.__age                 #self.__age私有变量

 

p1=Person("wulaoshi",18)

p2=Person("lilaoshi",28)

p1.__age = -1                                   #直接修改私有变量

print(p1.__age)

 

结果输出

D:\>py b.py

Traceback (most recent call last):

  File "b.py", line 27, in <module>

    print(p1.age)

AttributeError: 'Person' object has no attribute 'age'       #结果返回对象没有age属性

 

新变量p1.__age = -100与类中私有变量无关

class Person:

    def __init__(self,name,age):

        if isinstance(age,int) and age > 0:

            self.__age = age

        else:

            self.__age = 0

        self.name = name

   

    def set_age(self,age):

        if isinstance(age,int) and age > 0:

            self.__age = age

 

    def get_age(self):

        return self.__age

 

p1=Person("wulaoshi",18)

p2=Person("lilaoshi",28)

p1.__age = -100          #新变量,不是类中的私有变量

print(p1.__age)            #打印的也是新的变量值

print(p1.get_age())       #验证,私有变量未被改变

 

结果输出

D:\>py b.py

-100                           #返回新变量的值

18                               #返回私有变量的值,结果未改变类中私有变量的值

 

私有方法__print__age

class Person:

    def __init__(self,name,age):

        if isinstance(age,int) and age > 0:

            self.__age = age

        else:

            self.__age = 0

        self.name = name        #self.name实例变量,name局部变量

   

    def set_age(self,age):

        if isinstance(age,int) and age > 0:

            self.__age = age

 

    def __print__age(self):         #私有方法

        print(self.__age)

 

    def get_age(self):

        self.__print__age()        #通过其类当中他方法访问私有方法

        return self.__age

 

p1=Person("wulaoshi",18)

p2=Person("lilaoshi",28)

 

p1.get_age()         #通过类当中其他方法进行访问私有方法

结果输出

D:\>py b.py

18

 

p1.__print_age()    #不能直接访问私有方法

结果输出

D:\>py b.py

Traceback (most recent call last):

  File "b.py", line 30, in <module>

    p1.__print_age()

AttributeError: 'Person' object has no attribute '__print_age'

 

self.name实例变量:在所有类的所有方法,都可以访问到

name局部变量:在函数里面有效,出了函数就不可以使用。

 

类的函数:

>>> class P:

...     pass

...

>>> p=P()

>>> dir(p)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

>>> p.__class__

<class '__main__.P'>

 

内存解释:

class Person:

    def __init__(self,name):

        self.name = name

 

    def get_name(self):

        print(self.name)

 

    def get_name2(self):

        print(self.name,self.name)

 

p1=Person("wulaoshi")  #mmmzzz2

p1.get_name()            #self就是p1的内存地址

p1.get_name2()          #self就是p1的内存地址

 

p2=Person("李老师")    #mmmzzz3

p2.get_name()           #self就是p2的内存地址

p2.get_name2()             #self就是p2的内存地址

 

内存:

类Person放在内存地址:xxxyyy1

get_name():这个方法的调用要有一个self参数

 

实例p1放在内存地址:mmmmzzz2

name="wulaoshi"

 

p1.get_name()的调用过程

1)在xxxyyy1中先把get_name()的内容找出来

想去调用。当去调用的时候发现get_name()里面有个self

2)实例变量p1的内存地址 p1---> self=mmmmzzz2 传给 get_name() 这个方法

3)get_name(self=mmmmzzz2)

4)执行函数(方法体)内部的时候:print(self.name)

5)去mmmmzzz2找到name的值,然后打印,完成。

6)完成

 

Self的工作原理:

1)self是通过把实例的内存地址传递个方法内部,方法内部通过实例地址可以找到你想要的实例任何数据

2)类中的实例方法中的第一个参数self,实际就是实例所在的地址,通过这个地址,可以找到实例方法中需要使用的各种实例属性(数据)

 

类变量

"""

类内存:

存类的方法   #内存储的东西全局只有一份

类变量:谁都可以对它做修改,但是所有人读的值都是一样的

类变量是放在方法外面的,一般情况下是用在计算实例创建的数量

"""

class Person:

    x=0 #类变量

 

    def __init__(self,name):  #只有在实例化的时候才可以调用__init__的方法

        self.name = name

        Person.x+=1        #方法内使用类变量需要加上类的名字Person.x

 

    def get_name(self):

        print(self.name)

 

 

p1=Person("wulaoshi")       #实例化:类名+()+参数

p2=Person("lilaoshi")

 

print(Person.x)      #访问类变量

print(p1.x)        #也可以使用实例访问,返回的值是一样

print(p2.x)

 

实例化:p1=Person("wulaoshi")

实例对象:p1

实例方法:get_name

实例变量:self.name

 

继承、

class Person:

    def __init__(self,name):

        self.name = name

 

    def set_name(self,name):

        self.name = name

 

    def get_name(self):

        return self.name

 

class AsianPerson(Person):  #(Person)是AsianPerson父类

 

    def __init__(self,name,nation):

        Person.__init__(self,name)      #必须填写

        self.name = name                 # 可以不写self.name = name,

因为基于Person父类可以直接调用

        self.nation = nation

 

    def set_nation(self,nation):

        self.nation = nation

 

    def get_nation(self):

        return self.nation

 

ap= AsianPerson("laowang","china")

print(ap.get_name())

print(ap.get_nation())

ap.set_name("laolaowang")

print(ap.get_name())

 

p=Person("老李")        #创建父类实例调用的还是父类方法。

print(p.get_name())

 

#(Person)是AsianPerson父类,Person所有的方法AsianPerson都可以使用,基于原有的内容来做扩展

 

关于Person.__init__(self,name)的使用

class Person:

    def __init__(self,name):

        self.name = name

 

    def set_name(self,name):

        self.name = name

 

    def get_name(self):

        return self.name

 

class AsianPerson(Person):  #(Person)是AsianPerson父类

 

    def __init__(self,name,nation):

        #Person.__init__(self,name)   #因为没有使用父类的构造方法来把那name做初始化,所有想直接使用这个self.name就会失败。

        self.nation = nation

 

    def set_nation(self,nation):

        self.nation = nation

 

    def get_nation(self):

        return self.nation

 

ap= AsianPerson("laowang","china") #单独写不会报错

print(ap.name())    #打印会报没有name属性

 

使用Person.__init__(self,name) 可以调用Person全部的方法

 

  • 子类想使用父类的方法。变量,则必须在
  • 子类的构造函数中来完成父类实例的构造方法调用
    示例:

class AsianPerson(Person):

def __init__(self,name,nation):

Person.__init__(self,name)

 

  • 私有方法私有属性无法继承(不能直接使用,可以使用父类本身具有的方法继续操作),只能使用公用的方法和属性
  • 父类的__init__构造函数,是不会被子类继承的
  • 父类其他的公有变量和公有方法,可以被子类继承

 

 

class Person:

    def __init__(self,name):

        self.name = name

 

    def set_name(self,name):

        self.name = name

 

    def get_name(self):

        return self.name

 

class AsianPerson(Person):  #(Person)是AsianPerson父类

 

    def __init__(self,name,nation):

        Person.__init__(self,name)  

        self.nation = nation

 

    def get_name(self):      #重写了父类中的方法

        return "***:"+self.name

 

 

ap= AsianPerson("laowang","china")

print(ap.get_name())    #只会调用子类

 

 

    def get_name(self): #重写了父类中的方法

        return "***:"+super().get_name()        #表示在get_name方法里面调用了一下父类的get_name方法

执行结果:

D:\>py b.py

***:laowang

 

    def get_name(self): #重写了父类中的方法

        return "***:"+super().get_name() #表示在get_name方法里面调用了一下父类的get_name方法

ap= AsianPerson("laowang","china")

print(ap.get_name())    #只会调用子类   

执行结果:

D:\>py b.py

***:laowang          # 使用super().get_name()执行结果与上面一致

 

指令调用父类方法super().get_name()

重写:把父类的方法覆盖掉,使用子类的同名方法

重载:多个方法名一样,但是他们的参数类型,

还有参数个数不一样(针对java);

Python不支持重载

 

调用父类的方法(三种):

1)super().get_name()

2)return "***:"+Person.get_name(self)

3)super(AsianPerson,self).get_name()

 

父类中有操作私有变量的方法,子类可以操作父类的方法使用

class Person:

    def __init__(self,name):

        self.__name = name

 

    def set_name(self,name):           #父类本身具备修改私有变量的方法

        self.__name = name

 

    def get_name(self):

        return self.__name

 

class AsianPerson(Person):  #(Person)是AsianPerson父类

 

    def __init__(self,name,nation):

        Person.__init__(self,name)  

        self.nation = nation

 

 

ap= AsianPerson("laowang","china")

print(ap.get_name())    #只会调用子类

print(ap.set_name("laoli"))   #通过操作父类方法修改变量

print(ap.get_name())           #返回修改后的结果

 

返回结果

D:\>py b.py

laowang

None

laoli        #成功修改

 

私有变量不能直接访问或重写

class Person:

    def __init__(self,name):

        self.__name = name

 

    def set_name(self,name):

        self.__name = name

 

    def get_name(self):

        return self.__name

 

class AsianPerson(Person):  #(Person)是AsianPerson父类

 

    def __init__(self,name,nation):

        Person.__init__(self)  

        self.nation = nation

 

    def get_name(self):      #重写父类中的私有变量

        return self.__name       #父类中存在这种私有变量,子类不允许重写和访问

 

ap= AsianPerson("laowang","china")

print(ap.get_name())    #不能读取私有变量

 

返回结果:

D:\>py b.py

Traceback (most recent call last):

  File "b.py", line 20, in <module>

    ap= AsianPerson("laowang","china")

  File "b.py", line 14, in __init__

    Person.__init__(self)

TypeError: __init__() missing 1 required positional argument: 'name'

 

如果父类中有私有变量,那么子类的方法是不能读取父类中的私有变量

posted on 2021-11-16 22:59  Wgl123  阅读(14)  评论(0编辑  收藏  举报