day17-类和对象

总结

1. 类和对象

  • 如何创建类

    """
    定义类用代码描述清楚一个类是拥有那些相同功能和属性的集合。
    功能  -   对应的是函数
    属性  -   保存数据的变量(在类中叫属性)
    
    语法: -   创建类
    class 类名:
        类的说明文档
        类的内容
        
    说明:
    calss   -   关键字,固定写法
    类名  -   程序员自己命名(要求:是标识符,不是关键字   规范:见名知义,首字母大写,驼峰命名(单词之间采用首字母大写),不适用系统函数名,类名和模块名)
    :    -   固定写法
    类的说明文档      -   本质就是多行注释
    类的内容        -    包括属性和方法
                        属性分为:类属性(类的字段)和对象属性
                        方法分为:对象方法、类方法和静态方法
    
    注:方法就是定义在类中的函数
    """
    
    
    class Student:
       """
       学生
       """
       pass
    
  • 如何创建对象

    """
    语法:类()
    """
    
    if __name__ == '__main__':
       stu1 = Student()
       stu2 = Student()
       print(stu1, stu2)
    

2. 对象方法

  • 什么是对象方法

    """
    怎么定义:直接定义在内存中的函数(定义函数前不用加装饰器)
    怎么调用:用对象来调用 -   对象.方法名()
    特点:自带参数self,在调用的时候self不用传参,系统会自动将当前对象传给self(谁调用传谁)
    """
    
    class Person:
        """
        人类
        """
        def sleep(self, *, second=0, minutes=0, hours=0):
            print(f'休息{second+minutes*60+hours*360}秒钟...')
            time.sleep(second+minutes*60+hours*360)
            print(f'睡醒了')
    
        def eat(self, food=''):
            if not food:
                print('吃东西...')
            else:
                print(f'吃{food}')
    
        def __init__(self):
            pass
    
    
    if __name__ == '__main__':
        person = Person()
        person.sleep(second=3)
        person.eat('苹果')
    

3.构造方法和初始化方法

  • 构造方法

    # 函数名和类名相同
    # Python的构造函数在创建的类的时候由系统自动创建,程序员只需要在创建对象的时候自动调用
    
    class Dog:
        """
        学生
        """
        pass
    # 下面的这个函数的定义由系统自动完成
    # def Dog():
    #     新建好的对象 = 创建对象并且申请内存保存对象
    #     新建好的对象.__init__()
    #     return 新建好的对象
    #     pass
    
    # 2. 初始化方法      __init__
    """
    定义类的时候可以根据需求在类中添加对象方法:  __init__,添加的时候保证函数名是__init__,第一个参数是self
    除此之外我们可以随意添加参数到函数体。
    
    使用类创建对象的时候,系统会自动调用这个类中的__init__方法
    调用构造方法创建对象的时候需不需要参数,需要几个参数看这个类的__init__方法除了self以外有没有额外的参数。
    
    魔法方法:类中 方法名由__开头并且以__结尾的方法就是魔法方法, 所有的魔法方法都是自动调用的
    """
    
  • 初始化方法

    """
    定义类的时候可以根据需求在类中添加对象方法:  __init__,添加的时候保证函数名是__init__,第一个参数是self
    除此之外我们可以随意添加参数到函数体。
    
    使用类创建对象的时候,系统会自动调用这个类中的__init__方法
    调用构造方法创建对象的时候需不需要参数,需要几个参数看这个类的__init__方法除了self以外有没有额外的参数。
    
    魔法方法:类中 方法名由__开头并且以__结尾的方法就是魔法方法, 所有的魔法方法都是自动调用的
    """
    
    class Dog(object):
        def __init__(self):
            print('狗:__init__被调用')
            self.name = None
            self.gender = None
    
        def get_name(self):
            return self.name
    
    class Cat(object):
        def __init__(self, name, age):
            print('猫:__init__被调用')
            print(f'name:{name}, age:{age}')
    
    if __name__ == '__main__':
        dog1 = Dog()
        dog1.name = '小白'
        print(dog1.get_name())
        cat1 = Cat('小花', 3)
        cat2 = Cat('美女', age=1)
    
    
    # =========================补充===================:
    def __init__(x):
        print(f'自己的__init__被调用,{x}')
    
    def Cat(*args, **kwargs):
        def wrapper(*args, **kwargs):
            __init__(*args, **kwargs)
        wrapper(*args, **kwargs)
    
    Cat(12)     # 自己的__init__被调用,12
    

4. 属性

  • 属性

    # 属性是用来描述类的数据特征,属性的本质是保存数据的变量。
    
  • 对象属性和类属性

    """
    1) 类属性
    怎么定义:直接定义在类中的变量就是类属性
    怎么使用:通过类来使用,类.类属性
    什么时候用: 属性的值不会因为对象不同而不一样,这种属性就定义成类属性
    
    2)对象属性
    怎么定义:以'self.属性名=值' 的形式定义在__init__方法中
    怎么使用:通过对象来使用, 对象.对象属性
    什么时候用:属性的值会因为对象不同而不一样,这种属性就定义成类属性
    """
    
    
    class Person(object):
        """
        人类
        """
        # num就是类属性
        num = 16
    
        # name, age, gender是对象属性
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    if __name__ == '__main__':
        person1 = Person('小明', 18, '男')
        print(person1.name, person1.age, person1.gender)
        person1.name = '小虎'
        print(person1.name, person1.age, person1.gender)
        print(person1.num)
        print(Person.num)       # 16
    
    # 3. 对象属性赋初始值的三种方式
    
    # 方式一: 赋一个固定的值额
    # 方式二: 使用没有默认值的参数赋值
    # 方式三: 使用由默认值的参数赋值
    class Dog(object):
        """
        狗
        """
        def __init__(self, name, color, breed='土狗', gender='母'):
            self.name = name  # 赋没有默认参数的值
            self.breed = breed
            self.gender = gender # 赋有默认值参数的值
            self.color = color
            self.age = 1    # 赋固定的值
    
        # __repr__方法在当前类对象被打印的时候会被自动调用,这个方法的返回值(字符串)是说明就打印什么
        def __repr__(self):
            # return f'{self.name, self.age, self.gender, self.color, self.breed}: 汪汪...'
            # return json.dumps(self.__dict__)
            return f'<{self.__class__} date:{str(self.__dict__)}>'
    
    if __name__ == '__main__':
        dog1 = Dog('小黑', '黑')
        print(dog1)
    

5. 方法

  • 对象方法

    """
    怎么定义:直接在类中定义函数(函数前不加装饰器)
    怎么调用:对象.方法名()
    特点:自带参数self, self不用传参,谁调用self就指向谁
    什么时候使用:如果实现函数的功能需要用到对象的属性,一定是对象方法
    """
    class Goods:
        num = 10
        def func1(self):
            print('对象方法')
    
  • 类方法

    """
    怎么定义:在定义函数前加装饰器@classmethod
    怎么调用:类.类方法()
    特点:自带参数cls, cls不用传参,系统将当前类传给cls,谁调用就指向谁
    什么时候用:在不需要对象属性但是需要类属性的时候,就是用类方法
    """
    class Goods(Goods):
        @classmethod
        def func2(cls):
            print('类方法')
    
  • 静态方法

    """
    怎么定义:在定义函数前加@staticmethod
    怎么调用:类.静态方法
    特点:没有默认参数
    什么时候用:实现函数的功能既不需要当前类的对象也不需要当前类,就使用静态方法
    """
    class Goods(Goods):
        @staticmethod
        def func3():
            print('静态方法')
    
    
    goods1 = Goods()
    goods1.func1()	# 对象方法
    Goods.func2()	# 类方法
    Goods.func3()	# 静态方法
    

作业

  1. 定义一个狗类和一个人类:

    狗拥有属性:姓名、性别和品种 拥有方法:叫唤

    人类拥有属性:姓名、年龄、狗 拥有方法:遛狗

    class Dog:
        """
        狗狗
        """
        def __init__(self, name: str, gender: str, breed: str):
            self.name = name
            self.gender = gender
            self.breed = breed
    
        def bark(self):
            print(f'{self.name}: 汪汪...')
    
    
    class Person:
        """
        人类
        """
        def __init__(self, name: str, age: int, dog: Dog):
            self.name = name
            self.age = age
            self.dog = dog
    
        def walk_dog(self):
            print(f'{self.name}正在遛一条叫{self.dog.name}的狗狗')
            self.dog.bark()
    
    
    if __name__ == '__main__':
        my_dog = Dog("小黑", "公", "土狗")
        person1 = Person('小明', 18, my_dog)
        person1.walk_dog()
    
        # 小明正在遛一条叫小黑的狗狗
        # 小黑: 汪汪...
    
  2. 定义一个矩形类,拥有属性:长、宽 拥有方法:求周长、求面积

    class Rectangle:
        def __init__(self, long: float, wide: float):
            self.long = long
            self.wide = wide
        
        def perimeter(self) -> float:
            return 2*self.long + 2*self.wide
        
        def area(self) -> float:
            return self.long * self.wide
        
        
    if __name__ == '__main__':
        rec = Rectangle(10, 12)
        print(f'周长{rec.perimeter()}')
        print(f'面积{rec.area()}')
        
        # 周长44
        # 面积120
    
  3. 定义一个二维点类,拥有属性:x坐标、y坐标 拥有方法:求当前点到另外一个点的距离

    class Point:
        def __init__(self, x):
            self.position = (x,)
    
        def distance_another_point(self, another_point):
            return Point.two_point_distance(another_point, self)
    
        def __repr__(self):
            return str(self.position)
    
        @staticmethod
        def two_point_distance(point1, point2):
            return Point.two_point_distance_square(point1, point2) ** 0.5
    
        @staticmethod
        def two_point_distance_square(point1, point2):
            list1 = list(map(lambda item1, item2: (item1 - item2)**2, point1.position, point2.position))
            return sum(list1)
    
    class Point2D(Point):
        def __init__(self, x, y):
            self.position = x, y
    
    class Point3D(Point):
        def __init__(self, x, y, z):
            self.position = x, y, z
    
    if __name__ == '__main__':
        point1 = Point2D(14, 36)
        point2 = Point2D(-23, 41)
        print(f'point1到point2的距离是{point1.distance_another_point(point2)}')
        print(f'point1和point2的距离是{Point.two_point_distance(point1, point2)}')
    
  4. 定义一个圆类,拥有属性:半径、圆心 拥有方法:求圆的周长和面积、判断当前圆和另一个圆是否外切

    import math
    
    class Circle:
    
        pi = math.pi
    
        def __init__(self, radius, center: Point2D):
            self.radius = radius
            self.center = center
    
        def perimeter(self):
            return 2 * self.pi * self.radius
    
        def area(self):
            return self.pi * self.radius**2
    
        def is_excircle_another_circle(self, another_circle):
            return Circle.is_two_circle_excircle(self, another_circle)
    
        def __repr__(self):
            return f"<{str(self.__class__)[1:-1]} {str(self.__dict__)[1:-1]}>"
    
        @staticmethod
        def is_two_circle_excircle(circle1, circle2):
            center_distance = Point.two_point_distance_square(circle1.center, circle2.center)
            sum_radius = (circle1.radius + circle2.radius) ** 2
            if center_distance == sum_radius:
                return True
            else:
                return False
    
    if __name__ == '__main__':
        circle1 = Circle(8, Point2D(12, 34))
        circle2 = Circle(3, Point2D(-10, 23))
        if circle1.is_excircle_another_circle(circle2):
            print(f'{circle1}和{circle2}外切')
        else:
            print(f'{circle1}和{circle2}不外切')
    
  5. 定义一个线段类,拥有属性:起点和终点, 拥有方法:获取线段的长度

    class LineSegment:
        def __init__(self, start, end):
            self.start = start
            self.end = end
    
        def length(self):
            return self.end.distance_another_point(self.start)
    
    
    if __name__ == '__main__':
        line1 = LineSegment(Point(12), Point(100))
        print(f'线段的长度是{line1.length()}')
        line2 = LineSegment(Point3D(12, 123, 35), Point3D(100, 12, -834))
        print(f'线段的长度是{line2.length()}')
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值