1.类和对象
# 1.面向对象基础--- 类和对象
class A: # 使用class定义类
thing = '上课' # 类属性
def __init__(self, name): # init初始化,注意下划线
self.name = name # 实例属性
print(123) # 创建对象的时候,会自动调用init方法
def speak(self): # 实例方法
print('%s在说话' % self.name)
# 实例化对象 格式: 对象名 = 类名()
a1 = A('杨洪')
# 通过类名查看类属性
# print(A.thing)
# 通过对象查看类属性
# print(a1.thing)
# 通过对象来调用实例方法
# a1.speak()
# 1.类属性
# 1>类属性属于类,在init外部定义
# 2>所有实例对象共享的一个变量
# 3>类可以访问,实例对象也可以访问
# 2.实例属性
# 1>实例属性属于对象,在init内部定义
# 2>实例属性属于各个对象所有,互不干扰
# 3>类访问不到,实例才可以访问到
# 3.实例方法
# 由对象调用,至少有一个self参数,执行实例方法,自动将调用该方法的对象赋值给self
# 4.init方法
# 1>__init___方法是一个魔术方法,通常是用来做属性初始化或者赋值操作
# 2>类中没有写init,python会自动创建,不执行操作
# 3>为了完成自己想要的功能,自己定义init方法
# 1.面向对象:
# 程序设计的核心是对象
# 类:就是具有相同属性和功能的一类事物。(抽象)
# 对象:就是类的具体表现,是面向对象编程的核心。(具体)
# 类相当于制造飞机的图纸
# 已经创建的飞机就相当于对象
# 2.类
# class 定义类的关键字
# class Test: # Test是类名
# pass
# 三要素:类名、属性(对象的特征描述)、方法(对象具有的行为)
# 举例:
# 类名:人 Human 属性:身高、年龄 方法:跑、工作、走路
# class Human:
# name = '九歌' # 类属性
# 第一种:__dict__内置函数,可以查看类和对象中的所有属性
# print(Human.__dict__)
# print(Human.__dict__['name'])
# 第二种:通过.来查看
# 增删改查类中的单个属性
# print(Human.name) # 查看
# Human.name = 'if' # 修改
# del Human.name # 删除
# Human.age = 18 # 增加
# print(Human.age)
# 3.对象
# 创建对象的格式: 对象名 = 类名()
#
# class Test:
# mind = '哈哈' # 类属性
# # 类中创建的像函数一样的,是实例方法,自带self参数
#
# def work(self): # 实例方法, self表示当前调用方法的对象自己
# print('work中的:', self)
#
#
# t1 = Test() # 实例化一个对象, t1 = self
# print(t1)
# # 对象调用类中的方法
# t1.work()
# # 对象查看类中的属性
# print(t1.mind)
# 在方法内通过self获取对象属性
# class A:
#
# def test(self): # 实例方法
# print('%s的年龄是%d' % (self.name, self.age)) # a.name
#
# a = A() # 实例化对象 a = self
# a.name = 'zs'
# a.age = 18
# a.test() # 创建的对象去调用类中的方法
# 4.init方法(构造函数):初始化的作用 ,当类被实例化的时候,会自动执行该方法
# class Hero:
# mind = '哈哈' # 类属性
#
# def move(self): # 实例方法
# print('%s在移动中' % self.name)
#
# def __init__(self, name, hp, at):
# self.name = name # 实例属性,在init里面定义是实例属性
# self.hp = hp # 生命值
# self.at = at # 攻击力
# print(123)
#
# def attack(self): # 实例方法
# print('%s的生命值是%s, 攻击是%s' % (self.name, self.hp, self.at))
#
#
# # 实例化对象
# he = Hero('泰坦', 200, 600)
# he.move()
# he.attack()
# print(he.mind)
# # 一个类可以创建多个对象
# he2 = Hero('猴子', 100, 100)
# he2.move()
# he2.attack()
# print(he2.mind)
class Hero:
def __init__(self, name, hp, at):
self.name = name
self.hp = hp
self.at = at
print('Create a hero successfully!!!')
mind = 'oh my god'
def move(self):
print("{}正在快速'asdadas'移动,快追上她".format(self.name))
def attack(self):
print('%s的hp为%d,攻击是%d' % (self.name, self.hp, self.at))
y = Hero('yyc',9000, 234534)
y.move()
y.attack()
print(y.mind)
2.构造函数
# 4.init方法(构造函数):初始化的作用 ,当类被实例化的时候,会自动执行该方法
# class Hero:
# mind = '哈哈' # 类属性
#
# def move(self): # 实例方法
# print('%s在移动中' % self.name)
#
# def __init__(self, name, hp, at):
# self.name = name # 实例属性,在init里面定义是实例属性
# self.hp = hp # 生命值
# self.at = at # 攻击力
# print(123)
#
# def attack(self): # 实例方法
# print('%s的生命值是%s, 攻击是%s' % (self.name, self.hp, self.at))
#
#
# # 实例化对象
# he = Hero('泰坦', 200, 600)
# he.move()
# he.attack()
# print(he.mind)
# # 一个类可以创建多个对象
# he2 = Hero('猴子', 100, 100)
# he2.move()
# he2.attack()
# print(he2.mind)
class Hero:
def __init__(self, name, hp, at):
self.name = name
self.hp = hp
self.at = at
print('Create a hero successfully!!!')
mind = 'oh my god'
def move(self):
print("{}正在快速'asdadas'移动,快追上她".format(self.name))
def attack(self):
print('%s的hp为%d,攻击是%d' % (self.name, self.hp, self.at))
y = Hero('yyc',9000, 234534)
y.move()
y.attack()
print(y.mind)
3.析构函数
# 3. __del__ 析构方法
# 删除对象时,会默认调用__del__方法
# class Test:
# def __init__(self):
# print('我是init方法')
#
# def __del__(self): # 析构方法在对象销毁的时候将被调用
# print('我是del方法')
# print('被销毁了')
4.封装
# # 1.面向对象三大特性:封装、继承、多态
# # 2.封装
# # 1>将属性和方法放在一起作为一个整体,通过实例化对象来处理
# # 类中封装数据
# # 方法和属性在类里面都是封装,实例化对象就使用这些封装
# class Humam:
# def __init__(self, name):
# self.name = name # 实例属性
#
# def add(self): # 实例方法
# print('名字是:', self.name)
#
# # 实例化对象
# h1 = Humam('ts')
# # 通过对象直接调用被封装的内容
# # h1.add()
# # print(h1.name)
# 面向对象三特性:封装、继承、多态
# 私有权限
# _n: 私有属性或方法,只是声明一下,在外部还是可以调用
# __n: 私有属性或方法, 需要在内部使用
# class Test:
# name = '高高高' # 类属性(公有属性)
# _age = 18 # 私有属性
# __sex = 'nan' # 私有属性
#
# # 私有方法
# def __work(self):
# print('这是私有方法')
#
# def funa(self): # 实例方法
# # print(self.__sex) # 类内部查看私有属性
# print(self) # self 代表实例对象te 本身
# self.__work() # 类内部调用私有方法
# te = Test() # 实例化对象
# print(te)
# print(Test.name)
# te.funa()
# print(te._age) # 对象查看私有属性(单下划线开头)
# print(te._Test__sex) # 格式:._类名__属性名 (不推荐)
# 父类中包含私有属性
class A(object): # 父类
def __init__(self): # 初始化
self.num = 100 # 实例属性
self.__age = 18 # 私有属性
def test(self):
print('实例属性:', self.num)
print('私有属性', self.__age)
self.__funa()
def __funa(self):
print('这是父类的私有方法')
class B(A): # 子类
# 子类能不能在自己的方法内部,直接访问父类的私有属性
def demo(self):
print('这是子类的demo方法')
# 在子类中,不能直接访问父类的私有属性
# print('这是父类的私有属性', self.__age) # 错误
# 如果要调用父类的私有属性,可以调用父类的公有方法test
self.test()
b = B() # 实例化子类对象
b.demo()
# 在外界不能直接访问对象的私有属性
# print(b.__age)
# # 2>类中定义私有的
# # 定义私有权限,在变量名或者方法名前加上__(双下划线), 这个变量或方法就变成私有的了
# class A:
# name = 'zs' # 类属性
# __age = 18 # 私有属性(双下划线)
# _sex = 'nan' # 私有属性(单下划线)
# # 访问私有属性
# def test(self):
# print(self.__age)
#
# # a1 = A()
#
# # print(a1.name)
# # 私有属性,外部不能直接访问
# # print(a1.__age) # 错误的,不能直接在外部访问
# # print(a1._sex) # 单下划线开头,只是告诉别人这是私有属性,外部依然可以访问
# 外部访问双下划綫的私有属性: _类名__属性名,
# 但是最好不要这样做,了解
# # print(a1._A__age)
#
# # 类内部访问私有属性
# # a1.test()
#
# # 私有方法
# class B:
#
# def __test2(self): # 私有方法
# print(456)
#
# def test(self): # 实例方法
# # self.__test2() # 在类内部访问
# print(123)
#
#
# b1 = B()
# b1.test()
#
# # 总结:
# # 1. xx : 公有变量
# # 2._x : 单下划线开头,私有属性或方法,类对象可以访问到
# # 3.__x : 双下划线开头,私有属性或方法,无法在外部直接访问
# # 4.__xx__: 双前后下划线,魔术方法,不要自己发明这样的方法
# # 5.xx_: 单后置下划线,用于避免跟python关键词冲突
class A:
name = 'yyc'
_age = '12'
__address = 'wuhan'
def t1(self):
print('my name is: ', self.name)
def _t2(self):
print('my age is: ', self._age)
def __t3(self):
print('myaddress is: ', self.__address)
a1 = A()
a1.name = 'zd'
a1.t1()
a1._age = '1323'
a1._t2()
a1._A__address = 'jiujjiang'
a1._A__t3()
class B(A):
def t1(self):
print('B: my name is: ', self.name)
def bt2(self):
# A._t2(self)
super()._t2()
print('B: my age is: ', self._age)
def bt3(self):
print('B: my address is: ', self._A__address)
b1 = B()
b1.t1()
b1.bt2()
b1.bt3()
5.继承(单和多)
# 1.继承:
# 子类拥有父类的所有方法和属性
# 父类也叫基类,子类也叫派生类
# class Animal: # 动物类---父类
# def eat(self):
# print('吃东西')
#
# def sleep(self):
# print('去睡觉')
# 继承语法: class 子类名(父类名)
# 子类可以继承父类所有的属性、方法,就算直接没有,也可以直接使用父类中
# class Cat(Animal): # 猫类 -- 子类
# pass
#
# class Dog(Animal):
# pass
#
# cat = Cat()
# cat.eat()
# cat.sleep()
# dog = Dog()
# dog.eat()
# dog.sleep()
# python2.x版本中存在新式类、经典类
# python3.x版本中只有一种类:新式类(这个类默认继承object,object是python为所有对象提供的基类)
# 三种写法:并无区别
# 1.class A(object): # 推荐使用第一种
# 2.class A():
# 3.class A:
# 2.继承分为单继承、多继承
# 单继承:子类只继承一个父类
# class Person(object): # 父类
# def __init__(self, name):
# self.name = name
#
# def eat(self):
# print('%s在吃东西' % self.name)
#
#
# class Five(Person): # 子类
# pass
#
# p1 = Five('Mr Five') # 子类实例化对象
# p1.eat() # 子类对象可以直接使用父类中的方法
# 3.继承的传递性
# 儿子(子类)--爸爸(父类)--爷爷(父类的父类)
# 子类拥有父类以及父类的父类中的所有的属性和方法
# class Grandpa(object): # 爷爷类 -- 父父类
# def cool(self):
# print('我很帅')
#
#
# class Father(Grandpa): # 爸爸类 --- 父类
# def hair(self):
# print('我是发量王者')
#
#
# class Son(Father): # 儿子类 --- 子类
# pass
#
# xiaoming = Son()
# xiaoming.hair()
# xiaoming.cool()
# 4.重写
# 1>覆盖父类中的方法
# class Animal: # 动物类---父类
# def eat(self):
# print('吃东西')
#
# class Cat(Animal): # 猫类 -- 子类
# def eat(self):
# print('(>^ω^<)喵在吃东西')
#
#
# cat = Cat()
# cat.eat()
# 2>对父类方法进行扩展:在父类有的基础上,子类增加一些功能
# 1.父类名.方法(self) Animal.eat(self)
# class Animal: # 动物类---父类
# def eat(self):
# print('吃东西')
#
#
# class Cat(Animal): # 猫类 -- 子类
# def eat(self):
# Animal.eat(self)
# print('(>^ω^<)喵在吃东西')
# cat = Cat()
# cat.eat()
# 2.super().方法名() super().eat();
# super()就是使用super类创建出来的对象,
# 可以达到重写时保存父类中方法的效果
class Animal: # 动物类---父类
def eat(self):
print('我在吃东西')
def sleep(self):
print('我在睡觉')
class Cat(Animal): # 猫类 -- 子类
def eat(self):
super().sleep() # 不一定要跟父类中同名的方法
print('(>^ω^<)喵在吃东西')
cat = Cat()
cat.eat()
# 多继承
# 多继承:子类可以拥有多个父类,
# 并且具有所有父类的属性和方法
class A(object): # 父类一
def funa(self):
print('这是funa方法')
class B(object): # 父类二
def funb(self):
print('这是funb方法')
class C(B, A): # 子类
pass
# 创建子类对象
c1 = C()
c1.funa()
c1.funb()
# 继承的父类们中包含了相同的方法
# class Fat(object): # 父类一(爸爸)
# def play(self):
# print('我会玩木头')
#
#
# class Mom(object): # 父类二(妈妈)
# def play(self):
# print('我会跳绳')
#
#
# class Son(Mom, Fat): # 子类 谁先继承就用谁
# pass
#
# s1 = Son()
# s1.play()
# 子类对象调用方法的顺序,注意使用类名查看:类名.__mro__
# print(Son.__mro__)
# 总结:
# 如果多个父类有同名的属性和方法,
#默认使用第一个父类的属性和方法;
#多个父类中,不同名的属性和方法,不会有任何影响
6.多态
# 多态:同一种事物的多种形态
# python是强类型(不允许不同类型相加)的动态脚本语言
# 鸭子类型:不关注对象的类型,而关注对象具有的行为(方法)
# 多态:
# 1.不同的子类对象,调用相同的父类方法,产生不同的执行结果
# 2.可以增加代码的灵活度
# 3.以继承和重写父类方法为前提
# 4.调用方法的技巧,不会影响到类的内部设计
# 同样的+号,用于不同的对象,产生不同的结果
# print(1+1) # 计算作用
# print('he' + 'llo') # 连接作用
# 举例一:
# class Animal(object): # 父类
# def run(self):
# print('动物在走')
#
# class Dog(Animal): # 子类一
# def run(self):
# print('狗狗在走')
#
# class Duck(Animal): # 子类二
# def run(self):
# print('鸭子在走')
#
#
# class People(Animal): # 子类二
# def run(self):
# print('人类在走')
# 根据不同的对象做不同的事
# dog = Dog()
# dog.run()
# duck = Duck()
# duck.run()
# p1 = People()
# p1.run()
# # 举例二:
# class Dog(object): # 父类
# def __init__(self, name):
# self.name = name
#
# def play(self):
# print(f'{self.name}在玩耍')
#
# class Black(Dog): # 子类一
# def play(self):
# print(f'{self.name}在天上飞')
#
# class Human(Dog): # 子类二
# pass
#
#
# xiaohei = Black('小黑')
# xiaohei.play()
# h1 = Human('人类')
# h1.play()
#
class Dog():
def __init__(self, name):
self.name = name
def play(self):
print(f'{self.name}在天上飞!')
class Black(Dog):
def play(self):
super().play()
print('它飞得很开心')
class White(Dog):
def play(self):
Dog.play(self)
print('小白飞的很慢')
d1 = Dog('gougou')
d1.play()
b1 = Black('xaiohei')
b1.play()
w1 = White('baibai')
w1.play()
7.类方法、静态方法
# # 1.静态方法:类中的函数,不需要实例,不需要self
#
# # class Test:
# # # def funa(self): # 实例方法,自带self参数
# # # pass
# #
# # @staticmethod
# # def run():
# # print('这是静态方法')
# #
# # te = Test()
# # te.run()
#
# # 2.类方法:在内部直接访问类属性,或者调用其他的类方法
# class A:
# name = 'jiuge' # 类属性
#
# @classmethod
# def funa(cls): # 哪一个类调用的方法,cls就是哪一个类;
# print('这是类方法')
# # print(cls) # cls是类本身
# print(cls.name)
#
# @classmethod
# def set(cls, name): # 修改类属性
# cls.name = name
#
# def test(self):
# print('这是实例方法')
#
#
# # 用类方法对象类属性进行修改后,本身发生了改变
# a = A() # 实例化对象
# # print(A)
# # a.set('思思') # 实例对象调用类方法
# # a.funa()
# # 查看类属性
# # print(A.name)
# # print(a.name)
# # a.test() # 实例对象调用实例方法;类不能调用
# # A.funa() # 类调用类方法
#
# # 总结:
# # 实例方法:方法内部需要访问实例属性
# # 类方法:方法内部只需要访问类属性
# # 静态方法:方法内部,不需要访问实例属性和类属性
#
# # 1>.实例方法
# # 定义:第一个参数必须是实例对象,参数默认为self(类中定义),self代表实例对象本身
# # 调用:只能由实例对象调用
# # class A:
# # def funa(self):
# # print('实例方法')
# #
# # a1 = A() # 实例化对象
# # # A.funa() # 类调用实例方法(错误)
# # a1.funa() # 实例对象调用实例方法(正确)
#
# # 2>.类方法
# # 定义:使用装饰器@classmethod,第一个参数是当前类对象,参数默认为cls, cls代表类本身
# # 调用:实例对象和类对象都可以调用
# # class B:
# # @classmethod
# # def funb(cls):
# # print('类方法')
# #
# # b1 = B()
# # B.funb() # 类调用类方法 (正确)
# # b1.funb() # 实例对象调用类方法(正确)
#
# # 3>.静态方法
# # 定义:使用装饰器@staticmethod, 类中的一个函数,没有默认自带的参数
# # 调用:实例对象和类对象都可以调用
# # class C:
# # @staticmethod
# # def func():
# # print('静态方法')
# #
# # c1 = C()
# # C.func() # 类调用静态方法(正确)
# # c1.func() # 实例对象调用静态方法(正确)
#
# # 4>小案例:记录玩家游戏得分情况
# # (1)属性:
# # 玩家姓名:实例属性palyer记录
# # 游戏得分:类属性 top 记录分数
# # (2)方法:
# # 静态方法:help 显示游戏帮助信息
# # 实例方法:start 开始当前玩家的游戏
# # 类方法: show 显示游戏分数
# # (3)步骤:
# # 1.先查看帮助
# # 2.查看游戏分数
# # 3.创建游戏对象,开始游戏
# # 4.修改游戏分数
#
# class Game(object):
# top = 0 # 游戏得分初始值
# # 1.先查看帮助
# @staticmethod
# def help(): # 静态方法
# print('游戏即将开始')
#
#
# # 2.查看游戏分数
# @classmethod
# def show(cls): # 类方法
# print('游戏分数是:', cls.top)
#
#
# # 3.创建游戏对象,开始游戏
# def __init__(self, player): # 初始化
# self.player = player # 实例属性
#
# def start(self): # 实例方法
# print('%s开始游戏了' % self.player)
# # 4.修改游戏分数
# Game.top = 99
#
# # 1.查看帮助
# Game.help()
# # 2.查看游戏分数
# Game.show()
# # 3.创建对象,开始游戏
# g1 = Game('jiuge')
# g1.start()
# # 4.查看游戏后的分数
# Game.show()
#
#
# class Test:
# def play(self):
# print('this is a normal method')
#
# @staticmethod
# def run():
# print('this is a static method!')
#
# te1 = Test()
# te1.run()
# te1.play()
# # Test.play() #错误
# Test.run()
# class A():
# name = 'yyc'
# @classmethod
# def funa(cls):
# print('This is a class method')
# print(cls)
# print(cls.name)
#
# @classmethod
# def set(cls, name):
# cls.name = name
# a = A()
# #A.name = 'zd'
# a.set('as')
# a.funa()