一.今日主要内容
1.成员
在类中你能写的所有内容都是类的成员
2.变量
(1)实例变量:昨天写的就是实例变量,由对象去访问的变量.
(2)类变量(静态变量):此时,这个变量属于类,但是对象也可以访问

3.方法
(1)实例方法:昨天写的就是实例方法,使用 对象.方法() 进行调用
特点:在声明的时候,需要给出self,self必须放在第一个位置
在调用的时候,自动的会把对象传递给形参的self

(2)类方法(@classmethod):类方法是属于类的.
特点:在声明的时候需要给出一个能够接收类名的参数,cls,也必须放在参数的第一个
在调用的时候,自动的把xx对象的类传递给cls

(3) 静态方法(@staticmethod):静态方法也是属于类的,静态方法就好比,我们在类中定义了一个函数
静态方法一般和类方法差不多,使用类名去访问

4.属性(这个是比较有用的)
#为了在难受的时候舒服一点
在方法上添加一个@property,可以把一个方法变成一个属性,但是这个属性不可以被赋值
当我们某一个属性必须经过计算才能得到结果的时候
#我的理解:本质是方法,但是可以当成属性来用
5.私有
所有已双下划綫开头的方法,变量都是私有内容,外界无法访问//除非你主动暴露这些内容
你想保护就把他私有化
#总结:强化面向对象(今天量稍微大一些)
二.今日内容大纲
1.实例化变量
2.实例方法
3.类变量
4.类方法
5.静态方法
6.属性
7.私有

三.今日内容详解
1.实例变量
class Person:
def __init__(self,name,id,gender,birth):
self.name=name #实例变量 对象里的变量
self.id=id
self.gender=gender
self.birth=birth

p=Person('wusir','10086','不详','1900-12-15')


print(p.birth)
p.birth='1840-5-6' #实例变量可以进行修改
print(p.birth)

#实例变量一般使用 对象.属性

print(p.name)
2.实例方法
(1)
class Computer(object):
#实例方法
def play(self):
print('电脑可以扫雷')

#在定义实例方法的时候,必须给出一个参数 self
#形参的第一个参数,自动的把对象给传递进来
def work(self): #self 就是个形参,随便写,中文也行
print(self) #self 是当前类的对象
print('电脑用来工作')

c=Computer()
c.work() #调用的时候不需要手动给出self
print(c)

(2)

回顾之前
字符串操作. 列表操作. 字典操作. 元组操作.....
s = "你好啊"
s.replace("你", "我")
之前讲解的所有方法都是实例方法
3.类变量
class Person:
# country='中国' #类变量, 类变量是属于类的
country = '大清' #类变量不是特别特别常用
def __init__(self,name,gender):
self.name=name
self.gender=gender

p=Person('武sir','未知')
print(p.name) #实例变量
print(p.gender)
print(p.country) #类变量可以给对象使用

p2=Person('太白','两性')
print(p2.gender)
print(p2.country)

#大坑:没有修改类变量
p.country='大清' #没有修改类变量,只是在自己的实例化空间内创建了一个country
p2.country='大明'
print(p.country) #类变量可以给对象使用
print(p2.country)

Person.country='大元' #类变量最好是使用类名来访问
print(p.country)
print(p2.country)

 4.类方法

class Person:
#实例方法
def chi(self):
print('人会吃')

@classmethod #装饰器,此时这个方法是一个类方法,固定方法
def he(cls): #此时接收到的cls是类名
print(cls)
print('人会喝')
#用对象访问
p=Person()
p.he() #解释:在调用类方法的时候. 默认的把类名传递给类方法
#<class '__main__.Person'>
#人会喝
print(Person) #<class '__main__.Person'>

# 类方法一般用类名去访问
Person.he() # 类方法

# Person.chi() #这句话就会报错

# 总结:带类的最好用类来访问

5.静态方法

class Person:

@staticmethod #静态方法
def yue():
print('SKT')

#静态方法可以使用对象访问,
# 也可以使用类名访问,
# 但是一般推荐使用类名访问

p=Person()
p.yue()

Person.yue()
#知识点回顾:
#fromkeys共用value,返回新字典,不是原来的字典

6.属性

(1)引子

#怎么解决,每过一年都要加一年,把age 替换成 birth
class Person:
def __init__(self,name,gender,birth):
self.name=name
self.gender=gender
self.birth=birth #2000 2018
#年龄这一项,本来就应该是算出来的,而不是直接存储的
p1=Person('武sir','未知',2000)
age=2018-p1.birth #每个人都有年龄这个属性,但是又没办法存储
print(age)

(2)@property

class Person:
def __init__(self,name,gender,birth):
self.name=name
self.gender=gender
self.birth=birth #2000 2018
#年龄这一项,本来就应该是算出来的,而不是直接存储的
@property #把一个方法更改成一个属性,每次拿属性的时候都会自动的去执行这个方法
#方法的返回值就是属性值
def age(self): #实例方法
print('我是方法')
return 2018-self.birth
#注意:这里的属性是不能赋值的,方法不是变量
p1=Person('武sir','未知',2000)
print(p1.age) #看着像一个变量一样使用,实际上这里是调用的一个方法
print(p1.age)

# p1.age=99 #不可以修改的,因为age是一个方法,不是一个变量
#这句话修改会报错

7.私有     __

class Person:
__qie='潘潘' #私有类变量(或者叫做私有静态变量)
def __init__(self,name,mimi):
self.name=name
self.__mimi=mimi #__mimi代表的是 私有内容 实例变量
def gaosu(self):
print(f'把秘密告诉了太白,第二天所有人都知道了"{self.__mimi}"')
print(Person.__qie) #私有的类变量只能在类中调用,可以用类名调用
print(self.__qie) #私有的类变量只能在类中调用,可以用对象名调用

def __yue(self): #私有的实例方法
print('我要和宝宝约')

@staticmethod
def __koujiao():
print('韩志远希望和嫂子一起抠脚')

p=Person('wusir','和嫂子的故事')
p.gaosu()

# print(p.__mimi) #私有的内容只能在类里面调用,这里写会报错
#除非主动暴露自己的秘密,否则,不会
# print(Person.__qie) #这句话也会报错
# p.__koujiao() #也会报错
# Person.__koujiao() #也会报错

作业:

1. 简述⾯面向对象三⼤大特性并⽤用示例例解释说明?【背写】 

封装:对属性和方法的封装,以便随时调用

继承:子类除了本身之外还可以使用父类的方法和属性

多态:鸭子模型,同一个对象拥有多种形态

2.⾯向对象中的变量分为哪几种?并用示例说明区别?【背写】

(1)实例变量: 说白了,就是每个实例变量都应该拥有的变量,比如,人的名字,人的爱好
每个人的个人信息都属于实例变量..给对象用的

(2) 类变量(静态变量): 直接写在类中的变量就是类变量,需要用类名来访问,可以改变,多个对象共享的

3.⾯向对象中方法有哪几种?并用示例说明区别?【背写】 

1. 类方法         类名.方法   调用
2. 实例方法 对象.方法 调用
3. 静态方法 类名.方法 调用

4.面向对象中的属性有什么?并⽤用示例例说明? 

重点记忆(这个 没有理解好)

(1)@property 把方法转换成属性
(2)对象.属性(self.name)

5.简述静态方法和类方法的区别? 

记忆!!!
静态方法: 不用传递参数,没有继承
类方法: 需要传递参数,可以继承;访问类方法,默认传递的是类;

6.⾯向对象的⽅法中哪个无需传参数? 

记忆!!!

静态方法

7.面向对象中公有和私有成员,在编写和调用时有哪些不同? 

记忆!!!

编写,公有成员编写时,没有什么特别的要求,私有成员在成员名字前面需要加上__,双下划线,
公有成员在内部和外部都可以调用,私有成员只能在内部使用

网友:
公有使用: __xx__ 两端使用__
私有使用__xx 左端使用

8.

class Foo(object):
a1=11
a2=12
def __init__(self):
self.a1=1
obj=Foo()
print(obj.a1)
print(obj.a2)


结果:
1
12
分析:应该先找__init__里面的实例变量信息,再找类变量信息

9.

class Foo(object):
a1=11

def __init__(self,num):
# self.a2=num
self.a2=1
obj=Foo(999)
print(obj.a2)
print(obj.a1)

print(Foo.a1)
# print(Foo.a2) #因为第四行里是用类调用初始化方法里的变量,自然调用不到
#报错原因是,类中没有属性a2


结果:
999
11
11
第四行报错

 

10.

class Foo(object):
a1=1
__a2=2
a2=2

def __init__(self,num):
self.num=num
self.__salary=1000
# self.salary=1000
def get_data(self):
print(self.num+self.a1)
obj=Foo(666)
print(obj.num)
print(obj.a1)
# print(obj.__salary) #结果:Foo' object has no attribute '__salary'
# print(obj.salary) #自己测试结果:1000
# print(obj.__a2)
# print(obj.a2) #自己测试结果:2
print(Foo.a1) #结果:1
print(Foo.__a2)
# print(Foo.a2) #自己测试结果:2


结果:
666
1
找不到
找不到
1
找不到

11.

# 没问题,但是做这样的题目一定要仔细
class Foo(object):
a1=1
__a2=2

def __init__(self,num):
self.num=num
self.__salary=1000

def get_data(self):
print(self.num+self.a1)

obj1=Foo(666)
obj2=Foo(999)
print(obj1.num) #666
print(obj1.a1) #1

obj1.num=18
obj1.a1=99

print(obj1.num) #18
print(obj1.a1) #99

print(obj2.a1) #1
print(obj2.num+Foo.a1) #1000
print(obj2.num+obj1.a1) #1098

12.

#注意下面的四种玩法
class Foo(object):
hobby='大保健'
def __init__(self,num):
self.num=num
self.__salary=1000
def f1(self):
print(Foo.hobby)
@staticmethod
# def f2(self):
def f2(): #注意这个静态方法不能有self,有self不会调用
print(Foo.hobby)
@classmethod
def f3(cls):
print(cls.hobby)
@property
def f4(self):
print(Foo.hobby)
# print(self.hobby)
f=Foo(200)
f.f1()
f.f2()
f.f3()
f.f4

13.

class Foo(object):
@classmethod
def f3(cls):
print(cls)
Foo.f3() #结果:<class '__main__.Foo'>

14.

class Foo(object):
@classmethod
def f3(cls):
print(cls)
obj=Foo()
obj.f3() #结果:<class '__main__.Foo'>

15.

#我认为是一样的
#结果是一样的,和我推测的一样

class Foo(object):
@classmethod
def f3(cls):
print(cls)
def f2(self):
self.f3() #<class '__main__.Foo'>
Foo.f3() #<class '__main__.Foo'>
obj=Foo()
obj.f2()

16.

class Base(object):
@classmethod
def f3(cls):
print(cls)
def f1(self):
print('base.f1')
self.f3() #子类中有的话,用子类的,没有则用父类的
class Foo(Base):
# def f3(self):
# print('123')
def f2(self):
print('foo.f2')
self.f1()
obj=Foo()
obj.f2()

#结果:
foo.f2
base.f1
<class '__main__.Foo'>

17.请编写一个私有的静态方法,并通过代码证明私有方法不能再外部方法但可以在内部访问。

#注意,我们可以在内部通过,自己的类和未私有化的方法来调用私有化的静态方法
class Person:
__qie='潘潘' #私有类变量
def __init__(self,name,mimi):
self.name=name
self.__mimi=mimi #__mimi代表的是 私有方法
#
@staticmethod
def __donggua(self):
# def donggua(self):
print('你好啊!')
def gaosu(self):
# __donggua()
Person.__donggua(self)
print(f'把秘密告诉了太白,第二天所有人都知道了"{self.__mimi}"')
p=Person('wusir','和嫂子的故事')
# print(p.__mimi) #私有的内容只能在类里面调用
#除非主动暴露自己的秘密,否则,不会
p.gaosu()