1.面向对象 c1.py
# 面向对象
# 有意义的面向对象的代码
# 类,对象
# 类:
# 类的名字的第一个字母大写,第二个单词的首字母大写(函数/方法的首字母小写,第二个单词的首字母小写并且两个单词之间通过下划线连接)
# 类的名字后跟括号,括号后跟冒号
# 类里的'函数'不叫函数(称为方法);
# 不论涉及参数与否,类里的实例方法都必须传一个self关键字(否则会报错,其实这里的这个self也可叫别的名字,就和this一样;
# 但实际中约定俗成使用self这个名字;
# 在js中this不需要显示的声明,但这里需要;
# 这里的self就是实例方法的对象)
# 类里边的方法访问类里的函数,必须通过slef关键字加'.'操作符来实现
# 类的实例化,不需要通过new这个关键字来实现,直接使用类名加括号实例化即可
# 在类里边不能直接调用类的方法,会报错,只能在类的外边,实例化类以后同过点操作符来调用 (只负责定义,运行在外部)
# 类的最基本的作用:封装代码
# 方法和函数的区别:
# 方法:设计层面
# 函数:程序运行,过程式的一种称谓
class StudentHome():
name = 'qiyue' # 这个在类中一般不叫变量,而叫 数据成员(更能体现类的封装性)
age = 0
# 须传入self参数,这是一个固定的特征
def print_file(self):
print('name: '+self.name)
print('age: '+ str(self.age))
# 实例化类,通过类名+括号
# student = StudentHome()
# 调用类下的方法
# student.print_file()
2.使用 c2.py
# 在一个模块里定义一个类
# 在另一个模块引入,调用
from c1 import StudentHome
student = StudentHome()
student.print_file()
3.类和对象的区别 c3.py
# 类和对象的区别
# 类:是现实世界或者思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起;
# 类就像模板一样,通过类可以产生很多个对象;(类可以通过传入不同的具体值,可以产生很多个对象)
# 数据成员:刻画特征
# 方法:行为
# 构造函数:
# (1)自动执行,在实例化的时候自动触发(不需要显示的调用,但是是可以显示的调用的)
# 如果显示调用返回结果是none,不能强制返回(会报错);若想有返回,可以定义一个方法,在方法中return
# (2)构造函数会返回一个none,不能强制给一个return的值,会报错。所以一般不会通过构造函数return一个值,如果需要return一个值,还是通过普通函数来实现吧!
# (3)可以通过构造函数来使模板生成不同的对象
# (4)初始化类的属性
# (5)须加self参数
# (6)当直接打印构造函数的某个变量,如果该函数没有,则会往上寻找类的变量,若类的变量存在则打印类的变量
class Student():
# 这两个是类变量
name = 'qiyue'
age = 0
# 构造函数
# 类变量和实例变量(是不同的)
# 类变量:和类相关的变量
# 实例变量:和对象相关联一起的 (这个对象是有类这个模板创建的)
# 须加self
def __init__(self,name,age):
# 在这里给和对象相关的实例变量赋值
self.name = name
self.age = age
# 初始化类的属性
# print('do homework')
def do_homework(self):
print("do homework")
# 当类被具体实例化后,就变成了一个对象,
# (在类实例化过程中向类里传递一些具体参数,如果没有具体的数据的话就不是一个对象(因为还不具体,还是很抽象))
# 如果在__init__初始化的构造函数中有参数传入,则在实例化时必须也要传入参数,否则会报错
student1 = Student('石敢当',18)
student2 = Student('喜小乐',19)
print(student1.name)
print(student2.name)
# 在类的外部访问类的变量,通过 类名.变量名 的方式
print(Student.name)
4.类方法,静态方法,实例方法,构造方法 c4.py
# 访问类的变量,通过类的名字加'.'加类的变量名来访问
# 在类的内部还可通过self.__class__.类变量名来访问
# 类方法
# (1)一般使用cls(约定俗成)
# (2)通过@classmethod(装饰器)来声明是类方法
# (3)在类方法里访问类变量,直接通过cls.sum1(这里的cls就是这个类方法的类)即可
# (4)调用,是通过Student.add_sum来使用
# 类方法和实例方法的区别
# 实例方法关联的是实例本身,类方法关联的是类本身
# 类方法须加 @classmethod(类方法的装饰器)
# 类方法访问类变量直接 cls.sum2 (即 类.变量名) 就行;而实例方法须使用 self.__class__.sum1 实现;
# 静态方法
# (1)不需要像类方法和实例方法一样传入一个cls或者self
# (2)通过@ staticmethod(装饰器)声明静态方法
# (3)通过类或者实例来调用都可以
# (4)在其内部也可以访问类变量,通过Student.sum1(类名.类变量名)
# 注意点
# 不论是类方法还是静态方法都不能访问实例方法里的变量,所以建议直接使用类方法或者实例方法,少用静态方法(因为前两种,都办到它所实现的功能)
class Student():
sum1 = 0
sum2 = 0
name = 'qiyue'
age = 0
# 构造函数
def __init__(self,name,age):
self.name = name
self.age = age
self.__class__.sum1 += 1
# 访问类的变量名
# 在类的外部访问类的变量,通过 类名.变量名 的方式 ,例如:print(Student.sum1)
# 在类的内部还可通过 self.__class__.类变量名 来访问 (这里的 __class__ 指的就是 类 )
print('当前学生总数为: ' + str(self.__class__.sum1))
# 实例方法
# (定义时须传入self,在使用时不需要传参的;
# self只和对象有关,和类无关,谁调用了这个方法,这个self值的就是谁
# 即self指的是实例,而不是类)
def do_homework(self):
# self 指对象本身
print('do homework')
# 类方法
@classmethod # 类方法的装饰器
def add_sum(cls):
# 这里的cls指类本身
cls.sum2 += 1
print('sum2: ' + str(cls.sum2))
# 静态方法
@staticmethod # 静态方法的装饰器
def static_sum(x,y):
print(Student.sum1)
print('i am a static method')
student1 = Student('石敢当',18)
Student.add_sum()
# 通过对象也可调用类方法,但不建议这么做,最好使用类来调用类方法,例如:student1.add_sum()
student2 = Student('喜小乐',13)
# 类方法的调用
# 通过 类名.类方法名() 的方式
Student.add_sum()
# print(Student.sum1)
# 静态方法
# 可以通过类来调用;也可以通过对象来调用
Student.static_sum(1,2)
student1.static_sum(1,2)
5.成员的可见性 c5.py
# 成员的可见性
# public 公开的 private 私有的
# 如果想让某个方法(或者变量)私有 在这个方法(或者变量)前加双下划线(变量亦如此,前边加双下划线即可变为私有的变量)
# 例如:self.__score ; __add()之类的
# 内部方法和外部方法
# 类里的变量(即类的成员)的修改都应该通过方法来实现,而不应该通过直接对类的变量进行修改来实现(
# 通过方法来修改,可以在方法中做一些处理,对类的成员进行保护)
class Student():
name = 'qiyue'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
self.__score = 0
def __priv_method(self):
print('private')
def marking(self,score):
self.__score = score
print(self.name + '同学的成绩是: ' + str(self.__score) +'分')
def do_homework(self):
print('do homework')
def do_english_homework(self):
# 内部调用
self.do_homework()
print('do english homework')
student1 = Student('石敢当',18)
student2 = Student('小爱',18)
# 通过方法的方式来修改变量的值,比较提倡,
# 在方法中可以做一些逻辑处理(例如:不能打负分,当为负分时给提示之类的;
# 如果是变量,不能做逻辑处理判断,但方法就比较灵活了)
student1.marking(59)
# 私有方法,调用报错
# student1.__priv_method()
# 外部调用
# student1.do_homework()
# 这里并不是改变了私有变量__score的值,而是Python动态语言的特性,给student1扩展了一个__score变量(例如打印student2.__score就会报错)
student1.__score=-1
print(student1.__dict__)
print(student2.__dict__)
# print(student1.__score)
# print(student2.__score)
6.面向对象的三大特性 c6.py
# 面相对象的三大特性
# (1)继承性
# (2)封装性
# (3)多态性
class Human():
sum = 0
def __init__(self,name,age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
def do_homework(self):
print('this is parent method')
7.类的引入 c7.py
# 第一种写法,直接通过import,在使用时需要写为C6.Peopel
# import c6
# 第二种写法 通过from (推荐),使用时直接传入类的名字即可
from c6 import Human
class Student(Human):
def __init__(self,school,name,age,):
self.school = school
# 第一种调用方式: 不推荐使用该方法,如果使用了几十次,有一天父类变了,那就得改几十处名字,不太可取
# 这里是通过类来调用实例方法,所以必须要传入self
# Human.__init__(self,name,age)
# 第二种调用方式:通过super(第一个参数为子类的类名,第二个参数为需要传入的self参数) 这种方式比较推荐
# 优点:只需要更换括号中传入的父类名称即可,很方便
# super:父类的关键字
# super关键字不仅可用在构造函数中,也可用在其他的方法中
super(Student,self).__init__(name , age)
def do_homework(self):
super(Student,self).do_homework()
print('do son homework')
# 在父类中初始化须传入一些参数,子类继承后也须传入这些参数,同时须加上子类的初始化的参数
student1 = Student('人民路小学','石敢当',18)
# 通过类来调用实例方法,必须要传入self(这个有点可笑
# 既然已经将类实例化了,就可以直接通过实例化的student1.do_homework()
# 来调用即可,不必再次传入,而显得那么繁琐 )
# Student.do_homework(student1)
# 继承父类 (子类中是没有sum这个变量的,继承了父类)
# print(Student.sum)
print(student1.school)
print(student1.name)
print(student1.age)
# 允许,子类和父类的方法同名
# 当同名并不会报错
student1.do_homework()
# 开闭原则
# 修改封闭,扩展开放
(备注:以上内容来自七月老师的学习笔记,仅作为学习使用)