2018-10-19 Day 16 类的继承和点点pygame(水版)

""""""

"""
python中的类支持继承,并且支持多继承(一般不会使用,能不用就不能)

1.什么是继承

父类(超类):被继承的类
子类:去继承父类的类

继承就是让子类去直接拥有父类的属性和方法,继承之后父类的东西不会减少
python中所有的类都是直接或者间接的继承object


2.怎么继承
class 类名(父类):......
class 类名(父类): == class 类名(object):


3.能继承那些东西

注意:如果设置了__slots__会约束当前类的对象属性,并且会导致当前类的对象的__dict__属性不存在
继承后__slots__的值不会去约束子类的对象属性,但是会导致子类的__dict__有问题
"""

class Person:
    num = 61

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

    def eat(self, food: str):
        print('%s在吃%s' % (self.name, food))

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

    @classmethod
    def show_num(cls):
        print('人类的数量为%s亿' % cls.num)


class Student(Person):
    pass


s1 = Student('西欧安排王', 22)
print(Person.__dict__, s1.name, s1.age)
print(s1.__dict__)
s1.eat('🍎')
s1.func1()




""""""

"""
继承后子类会拥有父类的属性和方法,也可以添加属于自己的属性和方法

1.添加新的方法
  直接在子类中声明新的方法,新的方法只能通过子类或子类的对象来调用

2.重写
  子类继承父类的方法,想要在子类中重写实现这个方法的功能,直接声明和父类方法名一样的函数
  在子类中,方法通过super().父类方法去保留父类对应的方法的功能
  
3.类中的函数的调用过程
  类.方法(),对象.方法()

  先看当前类是否有这个方法,如果有就直接调用当前类中相应的方法,如果没有,回到当前类的父类中调用相应的方法
  如果有就调用,如果父类也没有,再去父类父类中找,依次直到object基类中去找,如果都没有程序就会崩溃

"""

class Person:
    num = 1

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

    def eat(self, food):
        print('%s在吃%s' % (self.name, food))

    @staticmethod
    def run():
        print('人在跑步')

    @classmethod
    def get_up(cls):
        print('先洗漱')
        print("换衣服")
        print(cls.num)


class Student(Person):
    num = 2

    def eat(self, food):
        print('喝一杯牛奶')
        super().eat(food)

    def study(self):
        print('%s在学习' % self.name)

    @staticmethod
    def run():
        print('学生在跑步')

    @classmethod
    def get_up(cls):
        # super() -> 获取当前父类
        # super().get_up() -> 调用父类的get_up方法
        super().get_up()    # 可以保留父类的get_up方法
        print('收拾书包')

p1 = Person('小王')
p1.eat('苹果')
Person.run()
Person.get_up()

stu1 = Student('小明')
stu1.eat('❦')
stu1.study()
Student.run()
Student.get_up()


""""""

"""
添加属性

1.添加字段:
  直接在子类中声明新的字段

2.添加对象属性
  子类通过继承父类的init方法来继承父类的对象属性



"""
class Car:
    num = 10

    def __init__(self, color):
        self.color = color
        self.price = '10W'

class SportCar(Car):
    # 修改字段的默认值
    num = 2
    wheel_count = 4

    def __init__(self, color, horsepower):
        # 通过super()来调用父类的Init方法,来继承父类的对象属性
        super().__init__(color)     # Car对象的init方法调用,传参color
        self.price = '20W'
        self.horsepower = horsepower

c1 = Car('white')
# 当子类中没有声明Init方法,通过子类的构造方法创建对象的时候,会自动调用父类的init方法
c2 = SportCar('red', 400)

print(c1.num, c2.num, c2.wheel_count)
print(c1.color, c1.price, c2.color, c2.price, c2.horsepower)


# 练习:声明一个Person类,有属性名字,年龄,身份证号码,要求创建人的对象的时候必须给名字
# 赋值,年龄和身份证可以赋值,也可以不赋值
# 声明一个Student类,也有属性名字,年龄,身份证号码,学号,成绩
# 要求创建学生的时候,必须给学号赋值,可以给年龄,名字,不能给身份证号赋值

class Person:

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

class Student(Person):

    def __init__(self, stu_id, name='小王', age=20, score=100):
        super().__init__(name, age)
        self.stu_id = stu_id
        self.score = score


s1 = Student('001')
s2 = Student('002','小李')
s3 = Student('003', '小明', 30, 40)

print(s1.name, s1.age, s1.stu_id, s1.id_card, s1.score)
print(s2.name, s2.age, s2.stu_id, s2.id_card, s2.score)
print(s3.name, s3.age, s3.stu_id, s3.id_card, s3.score)




""""""

"""
运算符重载:通过实现类相应的魔法方法来让类的对象支持相应的运算符(+ - * / // ** % > < ==)
实现了大于符号就实现了小于符号

值1 运算符 值2 ---> 值1.魔法方法(值2)
"""
a = 10 > 20     # int类实现了>对应的魔法方法__gt__
b = 10 < 20
c = 20 + 30
d = 1 * 2
max(1, 2)
print([''] * 4)

class Student:

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

    # __gt__就是>符号对应的魔法方法
    def __gt__(self, other):
        # self 相当于>符号前面的值,other相当于后面个值
        print(self.name, other.name)
        return self.age > other.age     # 比较学生的年龄

    # __lt__ <符号对应的魔法方法
    def __lt__(self, other):
        return self.score < other.score

    # __add__ +
    def __add__(self, other):
        return self.age + other.age

    # __mul__ *
    def __mul__(self, other):
        return self.score * other.score


stu1 = Student('小明', 40, 60)
stu2 = Student('小红', 30, 77)

print(stu1 > stu2)
print(stu1 < stu2)
print(stu1 + stu2)
print(stu1 * stu2)


import copy
import random

class Person:

    def __init__(self, name='张三', age=0):
        self.name = name
        self.age = age

    def __mul__(self, other: int):
        result = []
        for _ in range(other):
            result.append(copy.copy(self))
        return result

    def __gt__(self, other):
        return self.age > other.age

    # 定制打印格式
    def __repr__(self):
        return str(self.__dict__)[1:-1]


# 同时创建十个人的对象
person = Person()*10
for p in person:
    p.age = random.randint(12, 45)
    print(p.__dict__)
print('===========')
print(person)
print('============')
# 列表元素是类的对象,使用sort对列表进行排序
person.sort()
print(person)
print(max(person))


class Man:

    def __init__(self, name='张三', age=20):
        self.name = name
        self.age = age

    def __mul__(self, other: int):
        result = []
        for _ in range(other):
            result.append(copy.copy(self))
        return result


man1 = Man() * 4
print(man1)


""""""


"""
python中的内存管理 ---> 自动管理 ---> 垃圾回收机制

内存结构中分栈区间和堆区间,栈区间中的内存是系统自动开辟和释放的,堆区间中的内存需要手动开辟手动释放
但是目前绝大部分编程语言,都提供了一套属于自己的关于堆中的内存管理方案
python中的垃圾回收机制用来管理堆中内存的释放

python中的数据都是存在堆中的,变量是存在栈里面的,栈里面存的都是地址,都是堆中数据的地址

1.内存的开辟
python中将值赋给变量,会现在堆中开辟空间,将数据存起来,然后将数据地址返给变量,存在栈中
如果数据是数字或字符串类型,会现在缓存区中查看这个数据之前是否已经创建过,如果没有就创建空间存数据,
然后将地址返回,如果已经创建过,就直接将之前的地址返回给变量

2.内存的释放 ---> 垃圾回收机制
系统每隔一定的时间就会去检测当前程序中,所有的对象的引用计数值是否为0,如果对象的引用计数是0,
对象对应的引用计数就会被销毁,如果不是就不销毁

每一个对象都有一个引用计数的属性,功能是用来存储当前对象被引用的次数               
可以通过sys模块中的getrefcount去获取一个对象的引用计数的值

1.增加引用计数:增加引用(增加保存当前对象地址的变量的个数)

2.减少引用计数:
删除存储对象地址的变量
修改存储对象地址变量的值
"""

import copy
from sys import getrefcount as g
s1 = 'abc'
s2 = copy.copy(s1)
print(s1 is s2)
c = copy.deepcopy(s1)
print(c is s1)

aaa = [1, 2, 3]
b = aaa
print(g(aaa))

c = 10002321
print(g(c))

# 增加引用计数:
a1 = [2, 3, 4]
b1 = a1
list1 = [a1, 100]
print(g(a1))























最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容