第三十九课:类和对象:组合总结

课上总结:

class T:
    def __init__(self,x):
        self.num = x
class F:
    def __init__(self,x):
        self.num = x
class P:
    def __init__(self,a,b):
        self.t = T(a)
        self.f = F(b)
        print('水池里共有%d龟%d鱼'%(self.t.num,self.f.num))

这里将第三类中x,y改成a,b方便对比,对应T,F中的就该是a,b,这和上节课自己总结的一样结构为
self.变量 (属性的意思)= 类(形参)。
这里说一下这个形参,比如我想要1只龟10鱼,那么要输出的条件就是类T,F中的x为1,10,现在定义了P,来直接说明这个池子的两类,所以在P中直接将TF实例化,此时他们的形参就该和P同步,因为最后输入的时候是输入
pool = P (1,10)
整体逻辑就是,通过P输入数据,然后对应里面有两个另外类的实例化,并输入对应的数据,此时若要调用里面的函数就可以pool.(对应类的变量).(该类里面的函数)

需要注意的是,类.函数是不行都,类都需要一个对象,然后对象.函数

2.就是小甲鱼说的类,类对象,实例对象:
self(实例对象).属性 = 类
在这里插入图片描述
首先类对象相当于类下面定义的属性,它不会因为实例对象属性的变化而变化。若类对象即C.count变化,其属性变化,则abc实例都会跟着变化。
但是若实例化对象给自己属性赋值,这时候就不会再听命与大类的属性,而是将自己属性进行覆盖
若属性名和方法名重合,则属性会覆盖方法,因此定义名字和方法的时候尽量避免重复(属性:名词。方法:动词)

>>> class C:
    def x(self):
        print("Xman")

        
>>> c = C()
>>> c.x()
Xman
>>> c.x = 111  # 定义x属性
>>> c.x
111
>>> c.x()  # 方法已经被覆盖掉了,所以调用报错了
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    c.x()
TypeError: 'int' object is not callable

3.若将类实例化一个对象后,对对象进行赋值。然后删除类,此时实例化对象仍然可以用类的方法,因为已经存储在内存中

课后作业:
1.什么时候用组合,什么时候用继承?
答:根据实际应用场景确定。简单的说,组合用于“有一个”场景中,继承用于“是一个”场景中。例如,水池里有一个乌龟,天上有一只鸟,地上有一个小甲鱼,这些适合使用组合。丝瓜是瓜,女人是人,鲨鱼是鱼,这些就应该使用继承。

4.请问以下类定义中哪些是类属性,哪些是实例属性?

class C:
    num = 0
    def __init__(self):
        self.x = 4
        self.y = 5
        C.count = 6

答:num和count是类属性(静态变量),x和y是实例属性。大多数情况下,你应该考虑使用实例属性,而不是类属性(类属性通常仅用来跟踪与类相关的值)。

0.思考这一讲学习的内容,请动手在一个类中定义一个变量,用于跟踪类有多少个实例被创建(当实例化一个对象,这个变量+1,当销毁一个对象,这个变量自动-1)。

class A():
    n = 0
    def __init__(self):
        A.n += 1

    def __del__(self):
        A.n -= 1
a = A()
b = A()
c = A()
del a
print(A.n)

del的作用是在删除之前执行操作
类下面定义一个属性,然后用init,每次实例化时就会初始化一次,因此每次类属性都会改变。注意这里是A.n,而不是self.n,因为self只针对实例化对象,并不会叠加,A的话,每次输入一个,A就会增加,而且A不会变

1.定义一个栈(Stack)类,用于模拟一种具有后进先出(LIFO)特征的数据结构。至少需要有以下办法:
方法名 含义
isEmpty() 判断当前栈是否为空(返回True或False)
push() 往栈的顶部压入一个数据项
pop() 从栈顶弹出一个数据项(并在栈中删除)
top() 显示当前栈顶的一个数据项
botton() 显示当前栈底的一个数据项

class Stack():
    A = []
    def isEmpyt(self):
        if Stack.A == []:
            print('True')
        else:
            print('栈内有数据')
    def push(self):
        n = 1
        while n != 'y':  
            print('请输入一个数:',end='')
            Stack.A.append(int(input()))
            print('现在栈为:',Stack.A)
            n = input('任意键继续,y结束输入:')
    def pop(self):
        m =input('确认弹出一个栈顶数据项?y确定,任意键退出')
        while m == 'y':
           name =  Stack.A.pop(0)
           print('您弹出了数据%d'%name)
           print('现在栈为:',Stack.A)
           m = input('继续弹出请按y否则任意键:')
    def top(self):
        if Stack.A == []:
            print('抱歉,栈为空')
        else:
            print('栈顶的数据为:%s'%Stack.A[0])

    def botton(self):
        if Stack.A == []:
            print('抱歉,栈为空')
        else:
            num = int(len(Stack.A)) - 1 
            print('栈底数据为:%s'%Stack.A[num])
        
a = Stack()

别人方法的借鉴

def __init__(self, start=[]):
        self.stack = []
        for x in start:
            self.push(x)
def push(self, obj):  # 入栈
        print("成功入栈数据:", obj)
        self.stack.append(obj)

第一段学习到的是定义一个形参,然后如果形参不是空,是由数据的,则在输入栈之前会把形参数据先一步输入
第二段学习到的是利用形参完成input的功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值