类和对象

recode1.

1.类和对象的概念
  • 类:拥有相同属性和相同功能的对象的集合
  • 对象:类的实例
2.类的声明
  • class 类名:
    类的内容
3.对象的创建
  • 类() -创建一个对象
4.对象方法
  • a.直接声明在类里面,并且自带一个self参数
  • b.通过对象进行调用。对象.对象方法()
  • c.通过对象调用时,self不用传参,系统会将当前对象传给self
5.构造方法
  • a.函数名和类名一样的方法就是构造方法。用来创建对象
  • b.当使用构造方法创建对象的时候,系统会自动调用init方法对对象进行初始化
6.对象属性
  • a.声明在init方法中
  • b.self.属性 = 值
  • c.通过对象来调用
8.类的字段

声明在类中,函数的外面的变量


2.静态方法和类方法

类中的方法分为:对象方法,类方法和静态方法

1.对象方法
  • a.直接声明在类里面,并且有个默认参数self
  • b.通过对象调用
2.类方法
  • a.在声明前添加一个 @classmethod
  • b.有默认参数cls ,调用的时候不需要给cls传参,系统会自动将调用当前类方法的类传给cls
    cls最终指向的是一个类,类可以做的事情,cls都可以做
  • c.通过类去调用:类.类方法
3.静态方法
  • a.在声明前添加@staticmethod
  • b.没有默认参数
  • c.类.类方法()
4.对象方法、类方法和静态方法的选择
  • a.什么时候用对象方法:
    当实现函数功能需要用到对象的属性的时候就是要对象方法
  • b.什么时候用类方法
    实现函数的功能不需要对象的属性,但是需要类的字段或者需要类的时候就使用类方法
  • c.什么时候用静态方法
    实现函数的功能既不需要对象的属性也不需要类的时候就使用静态方法
class Person():
    #类的字段
    num =61
    def __init__(self,name):
        self.name =name
    #对象方法
    def eat(self,food):
        print("%s在吃%s"%(self.name,food))
    #类方法
    @classmethod
    def destory(cls):
        print("人类破坏环境")#人类破坏环境

        #可以用cls来创建对象
        p1 =cls("小明")
        p1.eat("面包") #小明在吃面包
        #可以用cls使用类的字段
        print(cls.num) # 61
    #静态方法
    @staticmethod
    def hit_animal():
        print("人类殴打小动物")

Person.destory() #cls =Person
Person.hit_animal()
练习:声明一个数学类,属性pi 功能:求两个数的和,求一个圆的面积
class Math:
    pi =3.1415926
    @staticmethod
    def sum_num(num1,num2):
        print("%d与%d的和为:%d"%(num1,num2,num1+num2))
    @classmethod
    def circle_area(cls,r):
        print("它的面积为:%f"%(cls.pi*r**2))


m1 =Math.circle_area(3)
m2 =Math.sum_num(1,3)

3.私有化

1.私有化

在类中,可以通过在属性名前,或者方法名前加 _ _ (注意:不能以_ _结尾),那么这个属性或者方法就会变成私有的。
私有的属性和方法在类的外部不能使用


class Person:
    __num = 100    # 私有的属性
    __number__ = 200   # 不是私有属性

    def __init__(self):
        self.name = '张三'
        self.__age = 18

    def __show_message(self):
        print(Person.__num)
        print('名字:', self.name, '年龄:', self.__age)

    def func1(self):
        self.__show_message()


# print(Person.__num)

p1 = Person()
print(p1.name)

# p1.__show_message()
p1.func1()

# print(p1.__age)

print(Person.__number__)

2.私有化原理

python中没有真正的私有化, 不能从访问权限上控制属性和方法的使用。
只是在名字前有 _ _ 但是没有以 _ _ 结尾的名字前再加了' _ 类名',导致不能直接通过原属性和方法名进行访问

class Dog:
    def __init__(self, name, color):
        self.__name = name
        self.__color = color


dog1 = Dog('大黄', '黄色')
print(dog1.__dict__)
# print(dog1.__name, dog1.__color)
print(dog1._Dog__name)

4.对象属性的getter和setter

1.getter和setter

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

2.添加getter
  • a.属性在命名的时候,属性名前加_(保护的) 例如:self._age =0
  • b.声明一个函数,函数的名字是属性名(不要下划线),不需要额外的参数,有返回值;
    并且函数前使用@property修饰,这个函数的返回值就是获取属性的结果

例如:
@property
def age(self):
return 年龄相关值

  • c.当需要获取属性的时候,通过对象.一个不带下划线的属性 例如:对象.age

3.给对象属性添加setter
想要给对象属性添加setter,必须先给它添加getter
a.属性在命名的时候,属性名前加_(保护的)
b.声明一个函数,函数的名字是属性名(不要下划线),需要一个额外的参数,不用返回值;并且函数前
使用@getter名.setter修饰
列如:
@age.setter
def age(self,value):
self._age =value
c.当需要给属性赋值的时候,通过对象.一个不带下划线的属性 列如:对象.age =100

class Person:
    def __init__(self,name ="小红"):
        self.name =name
        self._age =0
        self.sex ="男"
    #这儿的age函数就是属性_age的getter方法
    @property
    def age(self):
        if self._age<1:
            return "婴儿"
        elif self._age<10:
            return "小孩"
        elif self._age<30:
            return "青年"
        elif self._age<=100:
            return "老年"
    @age.setter
    def age(self,value):
        if not isinstance(value,int):
            print("年龄是整数")
            raise ValueError
        if not 0<=value<=100:
            print("超出范围!!")
            raise ValueError
        self._age =value
p1 =Person()
#这儿实质是在调用_age的getter方法
print(p1.age)
# print(p1.age) #希望取到的不是年龄值,而是年龄对应的阶段
# p1.age =-12 #存0
# p1.age =200 #存150
#这儿实质是在调用_age的setter方法
p1.age =98
print(p1.age)
练习:声明一个时间类,属性:以秒的形式保存时间不断的输入时间:以"xx:xx"形式输入。输入多少个时间,就保存多少个时间对象。直到输入end为止
class Time:
    def __init__(self):
        self._second = 0
    @property
    def second(self):
        return self._second
    @second.setter
    def second(self,value:str):
        times=value.split(":")
        self._second =int(times[0])*60+int(times[1])
while True:
    value =input("时间:")
    if value =="end":
        break
    t =Time()
    t.second =value
    print(t.second)

补充:打印自己声明的类的对象的时候,默认打印的是:<模块名.类名 object at 对象地址(id)>
如果不希望以默认的方式去打印对象,可以实现repr魔法方法。
打印对象的时候就会打印这个方法的返回值
def repr(self):
return"aaa"

class Student:
    def __init__(self,name,age):
        self.name =name
        self.age =age
    def __repr__(self):
        return "name:%s,age:%d"%(self.name,self.age)
        # return "<<"+self.__class__.__module__+"."+\
        # self.__class__.__name__+"object at "+hex(id(self))+">>"

stu1 =Student("小明",29)
stu2 =Student("小花",21)
print(stu1)

5.继承

1.继承

python中的类支持继承,并且支持多继承
python中默认情况是继承自object(object是python中所有类的基类)

(被继承者)(继承者)
父类 和 子类

继承就是让子类直接拥有父类中的内容

  • b.可以继承哪些内容
    • 对象属性
      类的字段
      对象方法
      slots魔法不会被继承
class Person:
    num =61
    def __init__(self):
        self.name ="张三"
        self.age =0
        self.sex ="男"
    def show_message(self):
        print("%s你好吗"%self.name)
    @classmethod
    def people(cls):
        print("世界有%d亿人"%cls.num)
#Student类继承Person
class Student(Person):
     pass
stu1 =Student()
print(stu1.name)
print(Student.num)
stu1.show_message()
Student.people()

6.添加方法

1.在子类中添加方法

子类除了拥有从父类继承的属性和方法,还拥有自己的属性和方法;

  • a.添加一个新的方法
    直接在子类中声明其他的方法;
    添加后子类可以用父类,父类不能用子类的
  • b.重写父类的方法
    完全重写 -覆盖父类的功能 - 直接在子类中重新实现父类的方法
    部分从写 - 保留父类的功能 ,添加新的功能 -
    在子类中实现父类的方法时通过super()去调用父类的方法,再添加新的功能

注意:

  • a.可以子类的方法中通过super()去调用父类的方法
    super(类,对象) - 获取对象中父类的部分(要求对象是指定的类的对象)

  • b.静态方法中不能用super

  • c.类中方法的调用过程
    通过类或者对象调用方法的时候,先看当前类中声明过这个方法,如果声明过,就直接调用当前类对应的方法
    如果当前类中没有声明过,会去找父类中有没有声明过这个方法,声明过就调用父类的方法;
    如果父类中也没有声明过,就去找父类的父类,然后以此类推直到找到object为止,
    直到object里面也没有才会报错

1.在子类中添加方法
```python
class Person:
    num =61
    def __init__(self):
        self.name ="张三"
        self.age =50
        self.sex ='男'
    def show_message(self):
        print("%s你好吗?"%self.name)
    @staticmethod
    def info():
        print("我是人类")
class Student(Person):
    def studay(self):
        print("%s在学习"%self.name)
    @classmethod
    def student_game(cls):
        print("%s在玩游戏"%cls.num)
    #完全重写
    @staticmethod
    def info():
        print("我是学生")
    #保留父类的功能
    def show_message(self):
        super().show_message()
        print("我去上学")
s1 =Student()
s1.studay() #张三在学习
s1.student_game()#61在玩游戏
Student.info() #我是学生
Person.info() #我是人类
s1.show_message() #张三你好吗?
                  #我去上学
p1 =Person()
p1.show_message() #张三你好吗?

7.添加属性

1.添加类的字段

直接在子类中添加新的字段

2.添加对象属性

继承对象属性是通过基础父类的init方法继承下来
如果想要在保留父类继承下来的对象属性的前提下,添加新的对象属性,
需要在子类的init方法中,通过super()去调用父类的init方法


class Person:
    num =61
    def __init__(self,name):
        self.name =name
        self.age =0

class Student(Person):
    number =60
    def __init__(self,name):
        super().__init__(name)
        self.study_id ="vvv"
print(Student.number,Student.num)
stu1 =Student("张三")
print(stu1.name,stu1.age,stu1.study_id)
练习:
声明一个动物类,有属性:年龄,颜色,类型。 要求:创建动物对象的时候类型和颜色必须赋值,年龄可以赋值也可以不赋值,声明一个猫类,有属性:年龄、颜色、类型,爱好,要求创建猫对象的时候,颜色必须赋值,年龄和爱好可以赋值,也可以不赋值,类型不能赋值。
class Animal:
    def __init__(self,color,type,age=5):
        self.age =age
        self.color =color
        self.type =type

class  Cat(Animal):
    def __init__(self,color,age=0,hobby ="call"):
        super().__init__("猫科",color,age)
        self.hobby =hobby

a1 =Animal("犬科","黄色",10)
c1 =Cat("黄色")
c2 =Cat("白色",10,"aaa")

你可能感兴趣的:(类和对象)