第020篇:面向对象2


1、私有化

严格来说,python类中的内容只有公开的;私有化是假的私有化。

访问权限

  公开的(public):类的里面、类的外面都可以用,也就可以被继承
  保护的(protect):类的里面可以使用,类的外面不能使用,也可以被继承
  私有的(private):只有类的里面可以用,类的外面不能用,也不能被继承

怎么私有化

在方法名前或者属性名前加两个下划线(__),但是名字后面不能加(__)
原理:并不是真的私有化,而是在两个下划线(__)开头前的属性名和方法名前加了 '_类名'

class Person:
    num = 61
    __num2 = 66

    def __init__(self, name, age=18):
        self.name = name
        self.age = age
        self.__gender = ''

    def func1(self):
        print('%s今年%d岁' % (self.name, self.age))
        print('--->', Person.__num2, self.__gender)

    @staticmethod
    def func2():
        print('我是静态方法')

    @staticmethod
    def __func21():
        print('我是静态方法')


print('=====默认的方法在外面都可以用=====')
print(Person.num)

p1 = Person('小白')
print(p1.name, p1.age)
p1.func1()

Person.func2()

print('=====私有的属性和方法=====')
# print(p1.__num2)
# print(p1.__gender)
# p1.__func21()
# print(p1._Person__gender)
# print(p1.__dict__)
代码演示

2、getter和setter

2.1、什么时候用:

  如果希望在给对象属性赋值前做点别的事情就给这个属性添加setter
如果希望在获取属性值之前做点别的什么事情就给这个属性添加getter

2.2、怎么用

注意:如果想要给属性添加setter必须先添加getter
getter:
    a、将需要添加的getter的属性名前加下划线(_)
    b、声明函数:
        声明前加@property
        函数名不带_的属性名
        函数需要一个返回值,返回值就是获取这个属性能够得到的值
    c、在外面使用属性的时候不带下划线
            
setter:
    a、声明函数:
        声明前加 @getter名.setter;
        函数名不带下划线(_)的属性名
        函数不需要返回值,但是需要一个参数,这个参数就是给属性赋的值
    b、在外面给属性赋值的时候不带下划线
class Person:
    def __init__(self):
        self._age = 10
        self._time = 1574749694.0996032

    @property
    def time(self):
        t_time = time.localtime(self._time)
        return '{}-{}-{}'.format(t_time.tm_year, t_time.tm_mon, t_time.tm_mday, )

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        print('value:', value)
        if isinstance(value, int):
            if 0 <= value <= 200:
                self._age = value
            else:
                raise ValueError
        else:
            raise ValueError


p1 = Person()
p1.age = 18
# p1.age = 'abc'
# p1.age = [12, 32, 12]

print(p1.time)


class Circle:
    pi = 3.1415926

    def __init__(self, r):
        self.r = r
        self._area = 0

    @property
    def area(self):
        return Circle.pi * self.r ** 2

    @area.setter
    def area(self, value):
        print('赋值:', value)


c = Circle(1)
print(c.area)   # 本质是在调用area函数:c1.area()

c = Circle(4)
print(c.area)

c.r = 10
print(c.area)

c.area = 2      # # 本质是在调用setter的area函数:c1.area()
getter和setter代码演示

3、继承

  继承是让子类直接用于父类的属性和方法
  子类 - 继承者(儿子)
  父类 - 被继承者(老子),又叫超类

3.1、 怎么继承

语法:
    class 类名(父类1, 父类2, ...):
        类的说明文档
        内容

3.2、继承哪些东西

  父类所有的属性和方法都可以继承
class Person:
    num = 66

    def __init__(self):
        self.name = '小明'
        self.age = 18

    @staticmethod
    def func1():
        print('静态方法')


class Student(Person):

    def func2(self):
        print(self.name)


# 子类直接使用父类的属性和方法
Student().func2()
Student().func1()
print(Student.num)
子类直接使用父类的属性和方法

  

  子类中添加属性和方法

1)添加方法和字段:
    在子类中直接声明新的字段和方法
注意:如果添加的字段名和方法名和父类的字段方法同名了,子类中的字段和方法会覆盖父类的字段和方法 -> 重写

2)添加对象方法
    在自己的init方法中添加新的属性,并且需要通过supper()去调用父类的__init__方法继承父类的对象属性

 

  supper的使用

可以在类中的任何一个对象方法或者类方法去通过supper()调用父类的对象方法或者类方法;不能调用静态方法。

super(类1,类1的对象).方法()  -->  调用类1中父类的方法
super().方法() <==> super(当前类, 当前类的对象)

super(type, obj) --> obj必须是type的对象或者是type的子类对象
class Animal:
    num = 100

    def __init__(self):
        self.age = 10
        self.gender = ''

    @staticmethod
    def a_func():
        print('Animal的方法1')

    def a_func1(self):
        print('动物中的对象方法')


class Cat(Animal):
    voice = '喵~'

    def __init__(self):
        super().__init__()  # 调用当前类的父类的方法
        self.color = '灰色'
        self.breed = '田园猫'

    @staticmethod
    def c_func1():
        print('猫中的静态方法')
        # 静态方法中不能使用supper()
        # super().a_func()

    def c_func2(self):
        super().a_func1()

print(Cat.num, Cat.voice)
Cat().a_func()
Cat().c_func1()

cat1 = Cat()
print(cat1.age, cat1.gender)

cat1.c_func2()
代码演示1
class A:
    def func(self):
        print('this is A')


class B(A):
    def func(self):
        print('this is B')


class D(A):
    def func(self):
        print('this is D')

class C(B):
    def func(self):
        # super().func()
        # super(C, self).func()
        # super(B, self).func()
        # super(D, D()).func()
        # super(A, A()).func()
        print('this is C')

obj = C()

# ==> super().func()
# obj.func()  # this is B; this is C

# ==> super(C, self).func()
# obj.func()   #  this is B;  this is C

# ==> super(B, B()).func()  /  super(B, self).func()
# obj.func()    # this is A;  this is C

# ==> super(D, D()).func()
# obj.func()    # this is A;  this is C

# ==> super(A, A()).func()
# obj.func()    # AttributeError: 'super' object has no attribute 'func'
代码演示2

4、多继承

 查看继承顺序: 先画出和需要的类相关联的所有的父类的继承关系,然后从左往右看没有子类的类

  print(D.__mro__)  用于查看继承顺序

  

class Animal:
    num = 100

    def __init__(self, age=0, gender=''):
        self.age = age
        self.gender = gender

    def a_func1(self):
        print('动物的对象方法')

    def message(self):
        print('this is Animal')


class Fly:
    flag = '飞行'

    def __init__(self, height=1000, time=3):
        self.height = height
        self.time = time

    @classmethod
    def f_func1(cls):
        print('飞行的类方法')

    def message(self):
        print('this is Fly')


class Bird(Animal, Fly):
    pass


class A1:
    def message(self):
        super(Bird, Bird()).message()


b1 = Bird()

# 字段都可以继承
print(Bird.num, Bird.flag)

# 方法都可以继承
b1.a_func1()
Bird.f_func1()

# 对象属性只能继承第一个父类的
print(b1.age, b1.gender)
# print(b1.height, b1.time)   # AttributeError: 'Bird' object has no attribute 'height'

b1.message()

A1().message()
代码演示1

class A:
    def message(self):
        print('this is A')


class B(A):
    def message(self):
        super().message()
        print('this is B')


class C(A):
    def message(self):
        super().message()
        print('this is C')


class D(B, C):
    def message(self):
        super().message()
        print('this is D')

class E(C):
    def message(self):
        super().message()
        print('this is E')

class F(D, E):
    def message(self):
        super().message()
        print('this is F')

class G(F):
    def message(self):
        super().message()
        print('this is G')

D().message()
"""
'this is A'
'this is B'
'this is D'
"""
print(D.__mro__)
代码演示2

class A:
    def message(self):
        print('this is A')

class B:
    def message(self):
        super().message()
        print('this is B')


class C(B, A):
    def message(self):
        super().message()
        print('this is C')

class D(B):
    def message(self):
        super().message()
        print('this is D')

class E(C):
    def message(self):
        super().message()
        print('this is E')

class F(D, E):
    def message(self):
        super().message()
        print('this is F')


class K(F):
    def message(self):
        super().message()
        print('this is K')


F().message()
print(F.__mro__)
代码演示3



优质内容筛选与推荐>>
1、软工第四次作业
2、ubuntu jdk环境变量配置
3、mysql对执行结果进行html格式的输出?输出html格式?
4、网上的意识流整理,
5、【2024】求X到Y之间的整数和


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn