面向对象--第二部分
面向对象三大特点
- 
 - 
继承:强调的父子类的关系。
 - 
多态:不同对象调用相同的方法,有不同的响应。
 
类的继承
- 
相关概念
- 
继承:父类的方法和属性,子类直接拥有,称为继承。
 - 
派生:子类在父类的基础上衍生出新的特征(属性和行为)。
 - 
总结:其实他们是一回事,只是描述问题的角度不同(继承强调相同点,派生强调不同点)
 
 - 
 - 
继承语法:
# class Animal: # 当没有写父类时,默认继承自object class Animal(object): def __init__(self, name): self.name = name  def run(self): print('小动物喜欢一天到晚跑个不停') # 继承自另一个类 class Dog(Animal): pass  d = Dog('旺财') # 直接拥有父类的属性 print(d.name) # 也拥有父类的行为 d.run()
 - 
派生示例
class Animal: def run(self): print('一天到晚不停的跑') class Cat(Animal): def eat(self): print('猫喜欢吃鱼')  c = Cat()  # 继承的方法 c.run() # 衍生的发生 c.eat() # 动态添加属性 c.color = '白色' print(c.color)
 
- 
方法重写
- 
父类的方法完全不合适,可以覆盖重写
 - 
父类的不是完全合适,可以添加完善
 - 
示例
class Animal: def eat(self): print('小动物一天到晚吃个不停')  def run(self): print('小动物一天到晚跑个不停')  class Cat(Animal): # 完全不合适,覆盖重写 def run(self): print('俺走的是猫步')  # 父类的方法不够完善,需要添加完善 def eat(self): # 保留父类方法中的内容 # Animal.eat(self) # 不建议使用 # super(Cat, self).eat() # 简化方案,推荐使用 super().eat() print('俺喜欢吃鱼') c = Cat() c.run() c.eat()
 
 - 
 - 
多继承:一个类可以有多个父类
class A: def eat(self): print('eat func in class A') class B: def eat(self): print('eat func in class B')  def test(self): print('test func in class B') class C(A, B): def eat(self): # 不重写方法,或者使用super,都是按照书写的先后顺序 # 默认会使用前面的类的方法 # super().eat() # 明确指定调用哪个父类的方法 B.eat(self)  c = C()  c.eat() c.test()
 
- 
访问权限
- 
权限
- 
公有的:类中的普通的属性和方法,默认都是公有的;可以在类外、类内以及子类中使用。
 - 
私有的:定义时在前面添加两个下划线即可,只能在本类中使用,类外及子类中不能使用
 
 - 
 - 
示例
class Person: def __init__(self, name): self.name = name self.__age = 20  def test(self): # 可以在类的内部使用 print(self.__age)  def __hello(self): print('hello world!') class Man(Person): def introduce(self): # 私有属性不能在子类中使用 print('我叫{},今年{}岁'.format(self.name, self.__age))  p = Person('小明') # print(p.name) # 当属性前添加两个下划线后,无法在外部访问 # print(p.age) # print(p.__age) # print(p.__dict__) # 默认加两个下划线的属性名前面添加了'_类名' # 不建议访问 # print(p._Person__age) # p.test()  # p.__hello()  m = Man('ergou') # m.introduce() print(m.__dict__)
 
 - 
 - 
类属性
- 
说明:定义在类中,但是在方法外的属性,通常会放在类的开头,这样的属性称为类属性
 - 
示例:
class Person: # 类属性 # nation = '中国'  # 限制对象可以使用的属性,可以提高访问的效率 __slots__ = ('name', 'age', 'nation')  def __init__(self, name): self.name = name self.nation = 'china' # 通过类名访问类属性 print(Person.nation) p = Person('小明') print(p.name) # 通过对象也可以访问类属性,但是不建议 print(p.nation)  # 特殊的类属性  # 类名字符串 print(Person.__name__)  # 基类组成的元组 print(Person.__bases__)  # 类相关的信息 print(Person.__dict__)  print(Person.__slots__)  p.age = 20 # p.xxx = 'yyy'
 
 - 
 
- 
类方法
- 
说明:
- 
通过类名调用的方法
 - 
定义时通过装饰器
classmethod进行装饰的方法 
 - 
 - 
作用:
- 
可以创建对象或简洁的创建对象
 - 
可以对外提供简洁易用的接口
 
 - 
 - 
示例1:创建对象
class Person: def eat(self): print('我喜欢吃麻辣烫,不要麻椒和辣椒')  # 定义类方法 @classmethod def test(cls): # cls:表示当前类 print(cls, '类方法')  @classmethod def create(cls): p = cls() p.age = 1 return p xiaoming = Person() xiaoming.eat()  # 类方法通过类名调用 Person.test()  # 创建或简洁的创建对象 xiaohua = Person.create() print(xiaohua.age)
 
 - 
 
- 
示例2:对外提供简单易用的接口
class Number: def __init__(self, num1, num2): self.num1 = num1 self.num2 = num2  def add(self): return self.num1 + self.num2  def sub(self): return self.num1 - self.num2  def mul(self): return self.num1 * self.num2  def div(self): if self.num2 == 0: return None return self.num1 / self.num2  @classmethod def pingfanghe(cls, num1, num2): n1 = cls(num1, num1) n12 = n1.mul()  n2 = cls(num2, num2) n22 = n2.mul()  n3 = cls(n12, n22) return n3.add() ret = Number.pingfanghe(3, 4) print(ret)
 
- 
静态方法
- 
说明:
- 
定义时通过装饰器
staticmethod装饰的方法 - 
也是通过类名进行调用
 
 - 
 - 
示例
class Person: @staticmethod def test(): print('static method test')  # 也可以创建对象 @staticmethod def create(): p = Person() p.age = 20 return p Person.test() p = Person.create() print(type(p))
 
 - 
 
- 
总结:
- 
凡是静态方法能够完成的功能都可使用类方法进行完成
 - 
若方法中没有使用到类名(cls),都可以使用静态方法
 
 - 
 - 
多态特性
- 
定义:不同的对象,调用调用相同的方法,有不同的响应。
 - 
示例:
class Animal: def run(self): print('小动物走道都不一样')  class Dog(Animal): def run(self): print('狗通常走S型')  class Cat(Animal): def run(self): print('猫一般走猫步')  def func(obj): obj.run()  func(Cat()) func(Dog())
 
 - 
 - 
属性函数
- 
说明:将成员方法当做属性一样进行访问。
 - 
作用:保护特定属性,或者对属性进行特定的处理。
 - 
示例:
class User: def __init__(self, username, password): self.username = username self.__password = password  # 可以保护指定的属性 @property def password(self): print('有人想偷看密码') return '想看密码,没门'  # 设置属性时,自动调用 @password.setter def password(self, password): print('加密存储密码') self.__password = '加密' + password + '加密' u = User('xiaoming', '123456') print(u.username, u.password)  u.password = 'abcd' print(u.__dict__)
 
 - 
 
练习
- 
设计一个银行系统
- 
类:银行卡类、用户类、操作类
 - 
 
 - 
 
                    
                
                
            
        
浙公网安备 33010602011771号