第十七天 面向对象程序设计的特点

面向对象

面向对象程序设计具有三大基本特征:封装、继承和多态,下面分别描述。

封装

封装是面向对象编程的核心思想,将对象的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。

采用封装思想保证了类内部数据结构的完整性,使用该类的用户不能直接看到类中的数据结构,而只能执行类允许公开的数据,这样就避免了外部对内部数据的影响,提高了程序的可维护性。

为什么要封装

封装数据的主要原因是:保护隐私

在python中用双下划线的方式实现隐藏属性(设置成私有的)

类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:

class A:
    __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
    def __init__(self):
        self.__X=10 #变形为self._A__X
    def __foo(self): #变形为_A__foo
        print('from A')
    def bar(self):
        self.__foo() #只有在类内部才可以通过__foo的形式访问到.


这种自动变形的特点:

  1. 类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
  2. 这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
  3. 在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
# -*- coding: utf-8 -*-
class C:           #正常情况
    def fa(self):  # 在定义时就变形为_A__fa

        print('from A')

    def test(self):

        self.fa()  # 只会与自己所在的类为准,即调用_A__fa

class B(C):

    def fa(self):

        print('from B')

b=B()   #在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
b.test()

输出:

from B
# -*- coding: utf-8 -*-
class C:		    	#把fa定义成私有的,即__fa
    def __fa(self):     # 在定义时就变形为_A__fa

        print('from A')

    def test(self):

        self.__fa()  # 只会与自己所在的类为准,即调用_A__fa

class B(C):

    def __fa(self):

        print('from B')

b=B()   #在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
b.test()

输出:

from A
@property的用法
class Rectangle:
    @property
    def width(self):
        # 变量名不与方法名重复,改为true_width,下同
        return self.true_width

    @property
    def height(self):
        return self.true_height


s = Rectangle()
# 与方法名一致
s.width = 1024
s.height = 768
print(s.width, s.height)

此时,如果在外部想要给width重新直接赋值就会报AttributeError: can't set attribute的错误,这样就保证的属性的安全性。

同样为了解决对属性的操作,提供了封装方法的方式进行属性的修改

class Rectangle(object):
  @property
  def width(self):
    # 变量名不与方法名重复,改为true_width,下同
    return self.true_width
  @width.setter
  def width(self, input_width):
    self.true_width = input_width
  @property
  def height(self):
    return self.true_height
  @height.setter
  #与property定义的方法名要一致
  def height(self, input_height):
    self.true_height = input_height
s = Rectangle()
# 与方法名一致
s.width = 1024
s.height = 768
print(s.width,s.height)

此时就可以对“属性”进行赋值操作

继承

继承是实现重复利用的重要手段,子类通过继承复用了父类的属性和行为的同时,又添加了子类的特有属性和行为。

为什么要继承

减少代码冗余、提高重用性

单继承
class grandFather():
  	print('我是爷爷')

class Parent(grandFather):
  	print('我是父类')
  
class SubClass(Parent):
	  print('我是子类')
    
sub = SubClass() 

#结果:		我是爷爷
#			我是父类
#			我是子类
#注意:类在定义的时候就执行类体代码,执行顺序是从上到下

属性查找顺序

对象查找属性的顺序:对象自己的 - > 所在类中 -> 找父类 - >父类的父类 ->Object

覆盖

也称之为重写 overrides
当子类出现了与父类名称完全一致的属性或是方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Asahi_aileen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值