Python练习task10:类与对象

对象 = 属性 + 方法

类主要定义对象的结构,我们通过类的模板来创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。

封装

封装是一种信息隐蔽技术。我们定义类可以使用关键字 class,后面紧跟类的名称、冒号和类的实现。

class Cat:
    #属性
    color='white'
    leg=4
    weight=10
    sound='meow'
    #方法
    def eat(self):
        print('I like eating fish')
    def play(self):
        print('I like playing with balls')
    def drink(self):
        print('I like drinking milk')
        
t=Cat()
print(t)
print(type(t))
print(t.__class__)
print(t.__class__.__name__)
t.eat()
t.play()
t.drink()
print(type(Cat))

在这里插入图片描述

继承

继承是子类自动共享父类之间数据和方法的机制。

class List(list):
    pass
t=List([3,8,6,10,2])
t.append(9)
t.sort()
print(t)

在这里插入图片描述

多态

不同对象对同一方法响应不同的行动。

class Animal:
    def run(self):
        raise AttributeError('子类必须实现这个方法')
class People(Animal):
    def run(self):
        print('People is walking')
class Turtle(Animal):
    def run(self):
        print('Turtle is crawling')
class Dog(Animal):
    def run(self):
        print('Dog is running')
def func(animal):
    animal.run()
func(People())

在这里插入图片描述

self

Python 的 self 相当于 C++ 的 this 指针。self代表类的实例,而非类。

class Test:
    def prt(self):
        print(self)
        print(self.__class__)

t = Test()
t.prt()

在这里插入图片描述
从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__则指向类。

Python的魔法方法

Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切。他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。

class Dog:
    def __init__(self, name):
        self.name=name
    def kick(self):
        print("我是%s,我会发出汪汪的声音" % self.name)
a=Dog("柴犬")
b=Dog("哈士奇")
c=Dog("金毛")
c.kick()

在这里插入图片描述

公有和私有

在 Python 中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会为私有的了。

class JustCounter:
    __secretCount = 0 
    publicCount = 0 
    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print(self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount) 
print(counter._JustCounter__secretCount)
print(counter.__secretCount)  

在这里插入图片描述

class Site:
    def __init__(self,name,age):
        self.name=name
        self.__age=age
    def who(self):
        print('name:',self.name)
        print('age:',self.__age)
    def __foo(self):
        print('这是私有方法')
    def foo(self):
        print('这是公共方法')
        self.__foo()
x=Site('MengZhou', '29')
x.who()
x.foo()
x.__foo()

在这里插入图片描述

继承

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印:

class Animal(object):
    def run(self):
        print('Animal is running...')

当我们需要编写Dog和Cat类时,就可以直接从Animal类继承:

class Dog(Animal):
    pass

class Cat(Animal):
    pass

对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类。Cat和Dog类似。
继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()方法:

dog = Dog()
dog.run()

cat = Cat()
cat.run()

在这里插入图片描述
无论是Dog还是Cat,它们run()的时候,显示的都是Animal is running…,符合逻辑的做法是分别显示Dog is running…和Cat is running…,因此,对Dog和Cat类改进如下:

class Dog(Animal):

    def run(self):
        print('Dog is running...')

class Cat(Animal):

    def run(self):
        print('Cat is running...')

在这里插入图片描述
当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。

组合

class Turtle:
    def __init__(self, x):
        self.num = x


class Fish:
    def __init__(self, x):
        self.num = x


class Pool:
    def __init__(self, x, y):
        self.turtle = Turtle(x)
        self.fish = Fish(y)

    def print_num(self):
        print("水池里面有乌龟%s只,小鱼%s条" % (self.turtle.num, self.fish.num))
p = Pool(1,10)
p.print_num()

在这里插入图片描述

类、类对象和实例对象

在这里插入图片描述
类对象:创建一个类,其实也是一个对象也在内存开辟了一块空间,称为类对象,类对象只有一个。

class A(object):
    pass

实例对象:就是通过实例化类创建的对象,称为实例对象,实例对象可以有多个。

a = A()
b = A()
c = A()

类属性:类里面方法外面定义的变量称为类属性。类属性所属于类对象并且多个实例对象之间共享同一个类属性,说白了就是类属性所有的通过该类实例化的对象都能共享。

class A():
    a = xx  #类属性
    def __init__(self):
        A.a = xx

实例属性:实例属性和具体的某个实例对象有关系,并且一个实例对象和另外一个实例对象是不共享属性的,说白了实例属性只能在自己的对象里面使用,其他的对象不能直接使用,因为self是谁调用,它的值就属于该对象。

class 类名():
    __init__(self):
        self.name = xx #实例属性

类属性和实例属性区别
类属性:类外面,可以通过 实例对象.类属性 和 类名.类属性 进行调用。类里面,通过 self.类属性 和 类名.类属性 进行调用。
实例属性 :类外面,可以通过 实例对象.实例属性 调用。类里面,通过 self.实例属性 调用。实例属性就相当于局部变量。出了这个类或者这个类的实例对象,就没有作用了。类属性就相当于类里面的全局变量,可以和这个类的所有实例对象共享。
注意:属性与方法名相同,属性会覆盖方法。

绑定

Python 严格要求方法需要有实例才能被调用,这种限制其实就是 Python 所谓的绑定概念。Python 对象的数据属性通常存储在名为.__ dict__的字典中,我们可以直接访问__dict__,或利用 Python 的内置函数vars()获取.__ dict__。

一些内置函数

issubclass(class, classinfo) 方法用于判断参数 class 是否是类型参数 classinfo 的子类。
一个类被认为是其自身的子类。
classinfo可以是类对象的元组,只要class是其中任何一个候选类的子类,则返回True。

class A:
    pass
class B(A):
    pass
print(issubclass(B, A))
print(issubclass(B, B))
print(issubclass(A, B))
print(issubclass(B, object))

在这里插入图片描述
isinstance(object, classinfo) 方法用于判断一个对象是否是一个已知的类型,类似type()。但是他们的区别在于type()不会认为子类是一种父类类型,不考虑继承关系,而isinstance()会认为子类是一种父类类型,考虑继承关系。如果第一个参数不是对象,则永远返回False。如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常。

class A:
    pass
class B(A):
    pass
print(isinstance(A(), A))
print(type(A()) == A)
print(isinstance(B(), A))
print(type(B()) == A)

在这里插入图片描述
hasattr(object, name)用于判断对象是否包含对应的属性。

class Coordinate:
    x = 1988
point1 = Coordinate()
print(hasattr(point1, 'x'))
print(hasattr(point1, 'no'))

在这里插入图片描述
getattr(object, name[, default])用于返回一个对象属性值。

class A(object):
    bar = 1
a = A()
print(getattr(a, 'bar')) 
print(getattr(a, 'bar2', 3))
print(getattr(a, 'bar2'))

在这里插入图片描述
setattr(object, name, value)对应函数 getattr(),用于设置属性值,该属性不一定是存在的。

class A(object):
    bar = 1


a = A()
print(getattr(a, 'bar'))  # 1
setattr(a, 'bar', 5)
print(a.bar)  # 5
setattr(a, "age", 28)
print(a.age)  # 28

在这里插入图片描述
delattr(object, name)用于删除属性。
在这里插入图片描述
另外还有几种内置函数:
class property([fget[, fset[, fdel[, doc]]]])用于在新式类中返回属性值。
fget – 获取属性值的函数。
fset – 设置属性值的函数。
fdel – 删除属性值函数。
doc – 属性描述信息。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值