面向对象基础(类封装继承等等)

接下来进入第五章的学习:面向对象基础

一、类

1.类(class):由3部分组成

类的名称:类名
类的属性:一组数据
类的方法:允许对其操作的方法(行为)

例如
#设计一个人类
类名: People
属性: 身高 体重 年龄 性别 
行为(方法):吃饭  睡觉 

2.那么我们该如何去定义类呢?

class 类名:
属性列表
方法列表

例如:定义一个猫类

class cat(object):          #继承object父类
    legs = 4                #这就是猫的属性
                   #像猫的其他属性如颜色什么的,每只猫都不一样,我们要后面用init去输入每只猫的颜色,这里放后面去讲          
                  
    def eat(self):          #这些就是猫的行为(方法)
        print('猫吃老鼠')
    def drink(self):
        print('猫喝水')

cat1=cat()  #这样cat1就有了cat的所有属性

print(cat1.legs)  #是4
cat1.eat()        #输出'猫吃老鼠'

3.类添加属性

在我们定义完一个类之后,创建了类的对象,我们可以手动给这个对象添加属性

定义一个人类
class Person(object):
    #属性:身高,体重,年龄
    #行为:吃饭 睡觉 喝水
    #定义一个普通方法
    def eat(self):
        print('人都要吃饭')

    #定义一个普通方法
    def sleep(self):
        print('人都要休息')
P=Person()
P.name = '张三'  #这样就给他添加上属性了

4.init()方法 (初始化方法)

class 类名:初始化方法,用来完成一些默认的设置
 def __init__(self):
        函数体语句      #类去赋值对象的时候会直接运行这个函数

例如定义一个汽车类

class cars(object):
    def __init__(self,color,wheelnum):
        self.color = color
        self.wheelnum = wheelnum

    def move(self):
        print('车子在移动...')
    def whistle(self):
        print('汽车在鸣笛')

car1=cars('white','4')     #就需要在赋类的时候输出参数
print(car1.color)
car1.move()

创建完之后依然可以修改其属性的值

car1.color='black'  #直接这样修改就好了

5.del()方法 (析构方法)

创建对象后,python解释器默认调用__init__()

同样,当删除一个对象的时候,python解释器也会默认调用__del__()

class Animal(object):
    #定义初始化方法  创建对象时候自动调用
    def __init__(self,name):
        self.name = name

    #定义普通方法
    def walk(self):
        print('动物会跑')

    #定义一个析构方法  删除对象的时候自动调用
    def __del__(self):
        print('%s对象被干掉'%(self.name))

dog = Animal('哈皮狗')
dog.walk()
del dog     #这时候会输出 哈皮狗对象被干掉
print(dog.walk()) #就会报错了

但是呢,要在对象的引用计数为0时,对象才是真正的被删除

#创建一个cat对象
cat = Animal('波斯猫')
cat2 = cat
cat3 = cat

print('删除对象1')
del cat
print('删除对象2')
del cat2
print('删除对象3')
del cat3
# 只有在cat3被删除后,才会输出 波斯猫对象被干掉

python 会在程序结束前自动调用del

总结:
变量保存了对象的引用,对象的引用计数加1,
使用__del__()删除对象的时候,对象的引用计数-1,对象被删除
如果对象的引用计数不是1,每删除一次对象的引用计数减1,直到引用计数为0时候
该对象才被真正的删除

6.魔方方法

魔方方法:
特殊方法:是指被包含下划线的方法或者所能调用到的方法的统称,这些通常会在特殊的情况下调用,并且基本没有手动调用他们的必要。

例如__str__ 定义一个车类

class Car(object):
    #定义初始化方法  创建对象的时候被自动调用
    def __init__(self,newColor,newWheelNum):
        self.color = newColor
        self.wheelNum = newWheelNum

    #定义一个析构方法  删除对象的时候被自动调用
    def __del__(self):
        print('%s对象被删除'%(self.color))

    #定义一个魔方方法
    def __str__(self):
        msg = '%s-%d'%(self.color,self.wheelNum)
        return msg

#创建一个对象laosi
laosi = Car('红色',4)
print(laosi)

总结:如果类的属性比较多,可以重写__str__()方法打印属性,方便阅读,无需手动调用,当使用print打印对象的时候,自动调用

7.重写一般方法和重写特殊的构造方法

重写涉及一个概念:继承

如果现在有两个类A(父类),B(子类) 如果子类B继承父A, ,类B的某个方法被调用的时候先从B中找,如果找不到再去A中找,如果在A找不到----》基类 (object)

class 命名(基类==父类):

#声明一个父类A
class A(object):
    #声明一个普通方法
    def sayHello(self):
        print('我是A')


#声明一个子类B
class B(A): #B类后面圆括号里面继承的父类名字
    #声明一个普通方法
    # def sayHello(self):
    #     print('我是B')

8.理解一下self

class Animal(object):
    #定义一个初始化方法
    def __init__(self,name):
        self.name = name

    #定义一个普通方法
    def printName(self):
        print('动物的名字是:%s'%self.name)  #self=dog

dog=Animal('哈士奇')
dog.printName()    #动物的名字是:哈士奇

总结:self可以理解成对象的本身

我们来做一个烤地瓜的应用熟悉一下类的使用

类名:SweetPotato

属性:根据数字判断地瓜的生熟度 0~3生的 3~5半生不熟 5~8烤熟了 8以上烤糊了,有番茄酱 芥末 蜂蜜

class sweetpotato(object):
def __init__(self):
    self.cooklevel = 0
    self.cookstring = '生的'
    self.condiments=[]

def cook(self,time):
    self.cooklevel += time
    if 0<self.cooklevel<=3:
        self.cookstring='生的'
    elif 3<self.cooklevel <=5:
        self.cookstring='半生不熟'
    elif 5 <self.cooklevel<=8:
        self.cookstring='烤熟啦'
    elif self.cooklevel >8:
        self.cookstring='烤糊了哈哈'

def addcondiments(self,condiment):
    self.condiments.append(condiment)

def __str__(self):
    str1='%s,%s'%(self.cookstring,self.condiments)
    return str1             #有这个就不用我一个个输出它的属性了

s = sweetpotato()

print('开始测试烤地瓜')
s.cook(4)
print(s)

s.cook(4)
print(s)

s.addcondiments('芥末')
s.addcondiments('蜂蜜')
print(s)

蛮有意思的 可以看看哈哈哈

9.访问限制

如果有一个对象,当需要对其进行修改属性:
1.直接修改 对象名.属性名 = 新数据
2.间接修改 对象名.方法名()

将属性定义为私有:__双下划线后面跟属性名

直接看例子把会更让人懂一些

#定义一个人类
class Person(object):
    #定义一个初始化方法
    def __init__(self,name,money):
        self.__name = name
        self._money = money

    #定义普通方法对属性设置
    def setName(self,value):
        #数据过滤
        if len(value) <= 4:
            self.__name = value
        else:
            print('名称的长度不能大于4个字符')
    #定义普通方法获取属性值
    def getName(self):
        return self.__name

    #定义私有方法
    def __sayHello(self):
        print('我的名字是:%s,我有%s存款'%(self.__name,self._money))

    #定义公有方法获取私有属性
    def test(self):
        self.__sayHello()

然后这时候我们创建一个对象p

p = Person('张三','99999999')
print(p.name)  #是不让访问的哦
Print(p.__name) #也同样不行
那应该怎么办呢?我们可以通过方法去访问他
print(p.gerNmae())
那么不能通过对象访问,自然也不能通过对象修改值了

同样啊,私有方法不能直接访问的

那么什么又是半公开属性呢,就是他是受保护的属性,Python中有个默认的规定,即在属性名前加上单个下划线(_属性名)来表示这是个受保护的属性,虽然Python解释器不会对使用单个下划线前缀的属性名做特殊处理,但程序员们会严格遵守这个约定,不会在类外部访问这种属性

私有属性为什么不能在类外访问?
因为_name python解释器将它转换成_Person__name,可以通过_Person__name访问,但是不建议这样做
p._Person__name = '李淑芬'
print(p.getName())

二、继承

继承的概念:在现实生活中,一般指子女继承父辈的基因,财产

1.单继承

一个子类继承父类的方法,但不会继承属性
class Cat(object):
#定义初始化方法
def __init__(self,name,color):
    self.name = name
    self.color = color
	
#定义一个普通方法
def eat(self):
    print('猫喜欢吃老鼠')

#定义子类Bosi继承父类Cat
class Bosi(Cat):
    #定义初始化方法
    def __init__(self,type,num):
        self.type = type

    def sleep(self):
        print('睡觉呢')

bosi=Bosi('bosi',4)
bosi.eat()           #'猫喜欢吃老鼠'

2.多继承

简而言之就是继承多个父类

class A(object):
    def test(self):
        print('test----A')

#声明一个父类B
class B(object):
    def test(self):
        print('test---B')

#声明一个子类,同时继承A和B两个父类
class C(A,B):
    def test(self):  #理解方法重写:比如语言  父母一般只会汉语 我们还会其他语言 比如英语 日语
        print('test----C')


#创建一个对象c
c = C()
c.test()   #是输出test----c,但如果没有这个,就是输出test-----A
print(C.__mro__)#可以打印查看执行方法的顺序
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

总结:一个子类同时继承了多个父类,如果调用同名的方法,先从子类找,子类没有到父类里面找根据就近原则

3.重写父类

重写父类其实就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖父类中的方法,跟刚刚讲的那个就近原则一样

class Person(object):
    #定义普通方法
    def lunch(self):
        print('人都需要吃饭')

#定义一个子类Student,继承父类Person
class Student(Person):
    #子类重写和父类同名的方法
    def lunch(self):
        print('学生需要吃饭')

#创建Student对象s
s = Student()
s.lunch()   #'学生需要吃饭'

那么子类要怎么样才能继承父类的属性呢

emm准确意义上来说不是继承父类的属性,是可以直接调用父类的__init__函数
class Person(object):
    #定义初始化方法
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    #定义普通方法
    def eat(self):
        print('人都需要吃饭')

    #定义普通方法
    def speak(self):
        print('我会汉语')

#定义子类Student继承父类Person
class Student(Person):
    #定义初始化方法
    def __init__(self,name,age,sex,no):        #有三种方法的
        # 调用父类同名方法
        #1.父类类名.父类初始化方法
        # Person.__init__(self,name,age,sex)
        # 2.super()
        # super().__init__(name, age, sex)
        #3.super()
        super(Student,self).__init__(name, age, sex)
        self.no = no


#创建一个对象
s = Student('张学友',20,'男',110)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值