python:类与对象

目录

一、类与实例对象

1.声明类和实例化对象

2.对象的属性和初始化

3.实例方法 

4.一切皆对象

5.类对象和类属性

 6.静态方法和类方法

二、类的简单继承

1.继承的简单使用

 2.重写父类方法和调用父类方法

3.多重继承

4.type与isinstance的方法

5.dir()和__dict__属性对比python:dir()和__dict__对比_qq_39935684的博客-CSDN博客dir()内置函数用于实例对象的属性及方法列表;__dict__:返回实例对象的内置属性字典;# dir内置函数与__dict__()的区别class Student(): def __init__(self, name, sex): self.name = name self.sex = sex def test(self): passs1 = Student('sxm', 'male')print(dir(s1)) .https://blog.csdn.net/qq_39935684/article/details/122434347

三、面向对象之封装

1.私有属性

2.私有方法


面向对象三大特性:封装、继承、多态

一、类与实例对象

1.声明类和实例化对象

python V2.X要求类继承原生object;python 3.X默认会添加原生Object类继承,无需手动添加;

# 声明类
class Person(object):
    legs_num = 2   # 类属性
    has_emotion = True

    def play_fire(self):  # 类方法
        print('玩火')

    def think(self):
        print('思考')

# 类对象 
print(Person)
# 创建实例对象;所谓对象,即一块内存空间
p1 = Person()
print(p1)
print(p1.legs_num)
p1.play_fire()
p2 = Person()
print(p2)

# 实例属性
p1.name = 'sxm'
print(p1.name)
p2.name = 'lisi'
print(p2.name)

del p1.name   # 删除p1实例对象的name属性
print(p1.name)

2.对象的属性和初始化

在创建类的时候,可以手动添加__init__()方法,该方法是一个特殊的类实例方法,成为构造方法(或构造函数);__init__()方法可以包含多个参数,但必须包含一个self参数,且必须作为第一个参数;

# 定义Person类
class Person(object):
    def __init__(self,name,age): 
        self.name=name    # 实例属性
        self.age=age
        print(id(self))


# 实例化Person类的实例对象:  类实例对象=类名(实例化参数)
alvin=Person("alvin",18)
yuan=Person("yuan",22)

print(id(alvin))

注意:__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以将各种属性绑定到self,因此self就指向创建的实例本身;

3.实例方法 

实例方法(或称为对象方法),指的是我们在类中定义的普通方法;只有实例化对象之后才可以使用的方法,该方法的第一个形参接收的一定是实例本身;

# 声明类
class Person(object):
    legs_num = 2   # 类属性
    has_emotion = True

    def __init__(self, name, age):
        self.name = name
        self.age = age
        print('self', self)

    def play_fire(self):  # 类方法
        print('玩火')

    def think(self):
        print('思考')

p1 = Person('sxm', 12)
p1.play_fire()   # p1实例对象调用play_fire()方法

4.一切皆对象

字符串,列表,字典等数据都是一个类,我们用的数据都是一个个的实例对象;区别就是,那些类是在解释器中注释好的,而我们使用的是自定义类;

5.类对象和类属性

# 声明一个类
class Student(object):
    banji = '31'   # 类属性,Student类的公有属性

    def __init__(self, name):
        self.name = name    # 实例属性

    def study(self, obj):    # 实例方法
        print('%s在向%s学习' % (self.name, obj.name))


# 创建实例对象
s1 = Student('sxm')
s2 = Student('sx')
s1.study(s2)     # 传参也可以传实例对象

 6.静态方法和类方法

类方法:使用装饰器@classmethod,第一个参数必须是当前类对象,该参数名一般约定为cls,通过他来传递类的属性和方法(不能传实例的属性和方法);

调用:类对象和实例对象都可以调用;

class Student():

    # 类属性
    cls_number = 68

    @classmethod
    def add_cls_number(cls):
        cls.cls_number+=1
        print(cls.cls_number)

Student.add_cls_number()

静态方法:使用装饰器@staticmethod,参数随意,没有self,cls参数,但是方法体重不能使用类或实例的任何属性和方法;

调用:类对象和实例对象都可以调用;

class Cal():

    @staticmethod
    def add(x,y):
        return x+y

    @staticmethod
    def mul(x,y):
        return x*y

cal=Cal()
print(cal.add(1, 4))
or
print(Cal.add(3,4))

二、类的简单继承

面向对象的编程带来的主要好处之一就是代码的重用,实现这种重用的方法之一就是通过继承机制,通过继承创建的新类或称为子类或称为派生类,被继承的类称为基类父类超类

1.继承的简单使用

在继承关系中,继承者完全可以替换被继承者,反之则不可以,例如我们可以说猫是动物,但不能是动物是猫,对于这个,我们称之为"向上转型";

特点:

  • 子类拥有父类非私有化的属性和方法
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
  • 子类可以用自己的方式实现父类的方法
class Animal():   
    def sleep(self):
        print('睡觉')

    def eat(self):
        print('吃饭')

class Cat(Animal):   # Cat类继承Animal类
    def catch_mouse(self):
        print('抓老鼠')

c1 = Cat()
c1.sleep()    # Cat的实力对象c1可以调用其父类Animal的sleep方法

 2.重写父类方法和调用父类方法

重写父类方法:

# 父类方法的重写
class Animal():
    def sleep(self):
        print('睡觉...')

class Cat(Animal):
    def sleep(self):     #子类Cat中的sleep覆盖了父类Animal中的sleep方法
        print('sleep...')

c1 = Cat()
c1.sleep()

父类方法的调用:

# 父类方法的调用
class Animal():
    def sleep(self):
        print('睡觉...')

class Cat(Animal):
    def sleep(self):
        # 方式1
        # Animal.sleep(self)
        # 方式2
        # super(Cat,self).sleep()
        # 或
        super().sleep()   # super()指的是父类的实例对象
        print('sleep结束')

c1 = Cat()
c1.sleep()

练习:

# 最后的打印结果是?
class A():
    def foo(self):
        print('A foo...')
    def bar(self):
        print('bar...')
        self.foo()

class B(A):
    def foo(self):
        print('B foo...')

b1 = B()
b1.bar()
# self.foo()调用的时候,调的是B类中的foo方法;因为self是b1
# 最后的打印结果是?
class A():
    def foo(self):
        print('A foo...')
    def bar(self):
        print('bar...')
        self.foo()

class B(A):
    def __init__(self, val):
        self.foo = val
    def foo(self):
        print('B foo...')

b1 = B('abc')
b1.bar()
#解:self.foo()会报错,self.foo()会先找foo变量,找到的是构造函数中的'abc';字符串是不能调用的,最后会报错 str object is not callable

3.多重继承

如果在继承元组中列了一个以上的类,那么它就被称为"多重继承";语法如下:

class SubClassName (ParentClass1[, ParentClass2, ...]):
    ...

当基类 SubClassName有多个父类ParentClass1和ParentClass2时,多个父类中方法出现重写情况时,执行时,执行排列在前的父类中的方法;当存在继承链式关系时,使用C3算法;

4.type与isinstance的方法

python:type和isinstance方法_qq_39935684的博客-CSDN博客isinstance()函数是python内置的函数,用于判断一个实例对象是否是一个已知的类型;# type和isinstance方法class Animal(): def est(self): print('eat...')class Dog(Animal): def swim(self): print('swim...')d1 = Dog()print(type(d1))# isinstance可以用于判断d1,是不是某个类的实例对象或https://blog.csdn.net/qq_39935684/article/details/122432690

5.dir()和__dict__属性对比python:dir()和__dict__对比_qq_39935684的博客-CSDN博客dir()内置函数用于实例对象的属性及方法列表;__dict__:返回实例对象的内置属性字典;# dir内置函数与__dict__()的区别class Student(): def __init__(self, name, sex): self.name = name self.sex = sex def test(self): passs1 = Student('sxm', 'male')print(dir(s1)) .https://blog.csdn.net/qq_39935684/article/details/122434347

三、面向对象之封装

封装指的是隐藏对象的属性和实现细节,仅对外提供公共访问方式;

追求"高内聚,低耦合"

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
  • 低耦合:仅对外暴露少量的方法用于使用

1.私有属性

class Student():
    def __init__(self, name, score):
        self.name = name
        self.score = score

s1 = Student('sxm', 100)
print(s1.score)

s1.score = 59
print(s1.score)

在class内部的属性和方法,在class外部代码可以通过直接调用实例变量来操作数据; 

私有属性:只有calss内部可以访问,外部不可以访问;

如果class外部代码需要访问私有变量score,可以定义get_score方法来访问;

如果calss外部代码需要修改私有变量score的值时,可以定义set_score方法;你也许会问,原先那种直接通过alvin.score = 100也可以修改啊,为什么要定义一个方法大费周折?因为在方法中,可以设置值时做其他操作,比如记录操作日志,对参数做检查,避免传入无效的参数等等;

class Student():
    def __init__(self, name, score):
        self.name = name
        self.__score = score

    def get_score(self):
        return self.__score

    def set_score(self, score):
        self.__score = score

s1 = Student('sxm', 100)

# class外部代码访问__score
print(s1.get_score())
# class外部代码重新赋值__score
s1.set_score(34)
print(s1.get_score())

对参数做检查: 

class Student(object):
    ...
    def set_score(self,score):
        if isinstance(score,int) and 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('error!')

注意:

  1. 这种机制并没有真正意义上限制从外部直接访问属性,知道了类名和属性名就可以拼出名字来访问:_类名__属性名;
    class Student():
        def __init__(self):
            self.name = name
            self.__score = score
    
    s1 = Student('sxm', 98)
    print(s1.__dict__)      # {'name': 'sxm', '_Student__score': 98}
    
    # 相当于在s1实例化的时候,将_Student__score = 98写入到了s1的实例对象所在内存空间中
  2. 变形的过程只在类的内部生效,在类外部定义后的赋值操作 ,变量名不会变形
    问:最后的s1.get_score()获取到的值是多少?
    class Student():
        def __init__(self, name, score):
            self.name = name
            self.__score = score     # 实例化的过程中,写入到s1实例对象内存空间中的变量名是_Student__score
    
        def get_score(self):
            return self.__score
    
        def set_score(self, score):
            self.__score = score     #读取时读取的是s1实例对象内存空间中_Student__score变量
    
    s1 = Student('sxm', 100)
    s1.__score = 34      #写入到s1内存空间时,写入的是__score变量名
    print(s1.get_score())
    
    #_Student__score变量与__score变量不冲突,所以最后获取到的值是100
  3. 单下划线、双下划线、首尾双下划线说明:
    __foo__:定义的是特殊方法,一般是系统定义的名字,例如:__init__()
    _foo:以单下划线开头的是protected类型的变量,即保护类型只能允许其本身与子类进行访问;(约定俗成,不限语法)
    __foo:双下划线表示有私有类型(private)的变量,只允许类本身访问;

2.私有方法

 在继承关系中,父类如果不想让子类覆盖自己的方法,可以将方法定义成私有的;

# 问c1.test()返回的结果是?
class Person():
    def __speak(self):    # 存储的是_Person__speak()方法
        print('speak...')

    def test(self):       # 在Person类内部,读取的是_Person__speak()方法
        self.__speak()      

class Child(Person):
    def __speak(self):    # 存储的是_Child__speak()方法
        print('咿呀学语...')

c1 = Child()
c1.test()
# 最后调用的是父类的__speak方法

四、面向对象之多态

https://blog.csdn.net/qq_39935684/article/details/122555451icon-default.png?t=LBL2https://blog.csdn.net/qq_39935684/article/details/122555451

五、面向对象之反射 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值