Python基础语法(八)面向对象

类定义

类中包含属性和方法,类通过class来定义

class Cat:
    """定义了一个Cat类"""

    #初始化对象
    def __init__(self, new_name, new_age):
        self.name = new_name
        self.age = new_age

    #打印对象信息
    def __str__(self):
        return "%s的年龄是:%d"%(self.name, self.age)

    #方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝kele.....")

    def introduce(self):
        print("%s的年龄是:%d"%(self.name, self.age))

#创建一个对象
tom = Cat("汤姆", 40)

lanmao = Cat("蓝猫", 10)

print(tom) #tom的年龄是:40
print(lanmao) #lanmao的年龄是:10

不用定义属性,属性在每个对象中是独立的

对象包含对象

class Home:
    def __init__(self, new_area, new_info, new_addr):
        self.area = new_area
        self.info = new_info
        self.addr = new_addr
        self.left_area = new_area
        self.contain_items = []

    def __str__(self):
        msg = "房子的总面积是:%d,可用面积是:%d,户型是:%s,地址是:%s"%(self.area, self.left_area, self.info, self.addr)
        msg += " 当前房子里的物品有%s"%(str(self.contain_items))
        return msg

    def add_item(self, item):
        #self.left_area -= item.area
        #self.contain_items.append(item.name)

        self.left_area -= item.get_area()
        self.contain_items.append(item.get_name())

class Bed:
    def __init__(self, new_name, new_area):
        self.name = new_name
        self.area = new_area

    def __str__(self):
        return "%s占用的面积是:%d"%(self.name, self.area)

    def get_area(self):
        return self.area

    def get_name(self):
        return self.name

fangzi = Home(129, "三室一厅", "北京市 朝阳区 长安街 666号")
print(fangzi) #房子的总面积是:129,可用面积是:129,户型是:三室一厅,地址是:北京市 朝阳区 长安街 666号 当前房子里的物品有

bed1 = Bed("席梦思", 4)
print(bed1) #席梦思占用的面积是:4

fangzi.add_item(bed1)
print(fangzi) #房子的总面积是:129,可用面积是:125,户型是:三室一厅,地址是:北京市 朝阳区 长安街 666号 当前房子里的物品有席梦思

bed2 = Bed("沙发",3)
fangzi.add_item(bed2)
print(fangzi) #房子的总面积是:129,可用面积是:122,户型是:三室一厅,地址是:北京市 朝阳区 长安街 666号 当前房子里的物品有席梦思,沙发

隐藏对象属性

class Dog:

    def __init__(self, new_name):
        self.name = new_name
        self.__age = 0#定义了一个私有的属性,属性的名字是__age

    def set_age(self,new_age):
        if new_age>0 and new_age<=100:
            self.__age = new_age
        else:
            self.__age = 0

    def get_age(self):
        return self.__age

dog = Dog("小白")
#dog.age = -10
#dog.name = "小白"

#print(dog.age)


dog.set_age(10)
age = dog.get_age()
print(age) #10

#dog.get_name()

#dog.__age = -10
print(dog.__age)#访问不了

私有方法

class Dog:

    #私有方法 方法前面加__
    def __send_msg(self):
        print("------正在发送短信------")

    #公有方法
    def send_msg(self, new_money):
        if new_money>10000:
            self.__send_msg()
        else:
            print("余额不足,请先充值 再发送短信")

dog = Dog()
dog.send_msg(100)

对象初始化

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

对象销毁

def __del__(self):
        print("对象销毁")
class Dog:
    
    def __del__(self):
        print("-----英雄over------")

dog1 = Dog()
dog2 = dog1

del dog1#不会调用 __del__方法,因为这个对象 还有其他的变量指向它,即 引用计算不是0
del dog2#此时会调用__del__方法,因为没有变量指向它了
print("====================")

打印结果:
-----英雄over------
====================
#如果在程序结束时,有些对象还存在,那么python解释器会自动调用它们的__del__方法来完成清理工作

sys 库中,getrefcount()函数可以获取对象引用个数,默认初始化一个变量后得到的数值是2,因为这个方法也对该对象进行了引用

实例属性

class Tool(object):
    def __init__(self, new_name):
        self.name = new_name


num = 0
tool1 = Tool("铁锹")
num+=1
print(num)
tool2 = Tool("工兵铲")
num+=1
print(num)
tool3 = Tool("水桶")
num+=1
print(num)

name为实例属性,tool1、tool2为实例对象,里面的属性不共享

类属性

class Tool(object):
    #类属性
    num = 0

    #方法
    def __init__(self, new_name):
        #实例属性
        self.name = new_name
        #对类属性+=1,调用格式:类名.类属性
        Tool.num += 1 

tool1 = Tool("铁锹")
tool2 = Tool("工兵铲")
tool3 = Tool("水桶")

print(Tool.num)

num为类属性,所有实例对象共享

实例属性类属性区别:
实例属性属于实例对象,每个实例对象拥有自己独有的实例属性,实例属性在多个类对象中不共享
类对象属于类,多个实例对象共享该类属性

实例方法、类方法、静态方法

class Game(object):

    #类属性
    num = 0

    #实例方法 必需要有self参数,调用实例属性
    def __init__(self):
        #实例属性
        self.name = "laowang"

    #类方法 需要加上@classmethod
    @classmethod
    def add_num(cls):#默认参数cls,调用类属性
        cls.num = 100

    #静态方法 需要加上 @staticmethod,方法中的参数可以添加变量,也可以不添加,取决于静态方法内部所使用的是类属性还是实例属性。。。
    @staticmethod
    def print_menu():
        print("----------------------")
        print("    穿越火线V11.1")
        print(" 1. 开始游戏")
        print(" 2. 结束游戏")
        print("----------------------")

game = Game()
#Game.add_num()#可以通过类的名字调用类方法
game.add_num()#还可以通过这个类创建出来的对象 去调用这个类方法
print(Game.num)

#Game.print_menu()#通过类 去调用静态方法
game.print_menu()#通过实例对象 去调用静态方法

静态方法可以通过类对象或者实例对象来进行调用。。。

实例方法,类方法,静态方法之间的区别及调用关系

实例方法,类方法,静态方法之间的区别及调用关系

如果只看这个图,很多人可能会看的一头雾水,特别是学过完全面向对象语言的同学, Python 是双面向的,既可以面向函数编程,也可以面向对象编程,所谓面向函数就是单独一个. py 文件,里面没有类,全是一些函数,调用的时候导入模块,通过模块名.函数名()即可调用,完全不需要类,那么你可能会问,那要类还有什么毛用? 类就是用来面向对象编程啦,类可以有自己的属性,类可以创建很多实例,每个实例可以有不同的属性,这也就保存了很多私有的数据,总之都有存在的必要.
再来看上面这张图,在类里面定义的函数就是方法,类方法需要@ classmethod 修饰并且有个隐藏参数 cls,实例方法必须有个参数 self, 静态方法必须有 @staticmethod修饰,类和实例都可以访问静态方法,实例可以访问实例方法也可以访问类方法,类可以访问类方法也可以访问实例方法,访问实例方法必须要带参数 self, 可以理解为类其实也是一个实例,类访问实例方法不带参数会报错的.类本身可以访问函数,实例却不行.

__new__方法

class Dog(object):
    def __init__(self):
        print("----init方法-----")

    def __del__(self):
        print("----del方法-----")

    def __str__(self):
        print("----str方法-----")
        return "对象的描述信息"

    def __new__(cls):#cls此时是Dog指向的那个类对象

        #print(id(cls))

        print("----new方法-----")
        return object.__new__(cls)
#print(id(Dog))
xtq = Dog()

创建一个对象,必需返回,否则创建失败,创建成功后调用init方法,调用成功后返回一个对象的引用

通过__new__方法创建一个单例并且实例属性只初始化一次

class Dog(object):

    __instance = None
    __init_flag = False

    def __new__(cls, name):
        if cls.__instance == None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            #return 上一次创建的对象的引用
            return cls.__instance

    def __init__(self, name):
        if Dog.__init_flag == False:
            self.name = name
            Dog.__init_flag = True

a = Dog("旺财")
print(id(a))
print(a.name)

b = Dog("哮天犬")
print(id(b)) #与a的id相同
print(b.name) # 打印结果:旺财

你可能感兴趣的:(Python基础语法(八)面向对象)