面向对象之类的成员,嵌套

成员和嵌套(组合)

面向对象 Object Oriented Programing


类的成员可分为三大类:字段丶方法和属性

成员

类的特性

  • 封装
  • 1、防止数据被随意修改
  • 2、使外部程序不需要灌注对象内部的构造,只需要通过此对象对外提供的接口进行直接访问即可

  • 继承

  • 1、类可以派生出子类
  • 2、父类里定义的属性、方法自动被子类继承
  • 3、通过父类=>子类的方式以最小代码量的方式实现
    不同角色的共同点和不同点同时存在

  • 多态

  • 一个接口,多种实现;父类派生出不同的子类,子类在继承父类的相同方法同时又对父类的方法做了不同的实现,这也就是同一种事物表现出的多种形态。
  • 例:人类是一个父类,派生出中国人、美国人、西班牙人等子类,子类继承使用talk()方法,但不同人所说语言不同,talk()方法根据不同人表现出不同的交谈语言(中文、英文…)。
  • 即对不同对象发出的消息将会有不同的行为。例如:老板只要发出消息(工作),不同的员工对象将会按自己的职能进行不同的工作。

一丶字段

1.类的成员:变量,方法,属性

变量:

  实例变量(字段)

    公有实例变量(字段)

1 class Foo:
2     def __init__(self,name):
3         self.name = name#公有实例变量
4     
5      def func(self):
6         return self.name

 

    私有实例变量(字段)

1 class Foo:
2     def __init__(self):
3         pass
4     def __func(self):
5         print("私有实例变量")
6 
7 obj = Foo()
8 obj.func()#此处无法调用

 

  类变量(静态字段)

    公有类变量(静态字段)

 1 class Foo:
 2     a = 1#公有类变量
 3     def __init__(self):
 4         pass
 5     def func(self):
 6         return self.a
 7 
 8 obj = Foo()
 9 print(obj.a)
10 print(Foo.a)

 

    私有类变量(静态字段)

1 class Foo:
2     __a = 1
3     def __init__(self):
4         pass
5     def func(self):
6         print(self.a)#不能引用,错
7 
8 obj = Foo()
9 obj.func()

总结:

  公有实例变量可以在类的方法中使用,也可以用实例化的对象调用

  私有实例变量不能在对象调用,只能在类中用其他方法调用后,再使用对象调用

  公有类变量可以在类中调用,也可以用对象调用

  私有类变量只能在类中使用其他方法调用,不能使用对象调用,子类也不能调用(如果必须要用,先在父类中使用方法来调用这个私有类变量,再在子类中调用这个方法)

 

方法:

  实例方法

  

1 class Foo:
2     def __init__(self,name):
3         self.name = name
4     def func(self):#实例方法
5         print(self.name)
6 
7 obj = Foo("abc")
8 obj.func()

 

  静态方法

1 class Foo:
2     def __init__(self,name)
3         self.name = name
4     @staticmethod#静态方法
5     def display(a1,a2):
6         return a1 + a2
7 
8 Foo.display(1,2)
#如果无需使用对象中封装的值,就可以使用静态方法

 

  类方法

1 class Foo:
2     @classmethod
3     def show(cls,x1,x2):#默认第一个参数是类(cls)
4         print(cls,x1,x2)
5 
6 ret = Foo.show(1,2)
7 print(ret)

总结:

  实例方法:至少有一个参数,第一个参数必须是实例对象,默认是self

  静态方法:可以没有参数,也无需使用对象中封装的值,方法上面需要加@staticmethod

  类方法:至少有一个参数,第一个参数必须是类,默认是cls,方法上面需要加@classmethod

 

属性(通过方法改造出来):

  

 1 class Foo:
 2     def __init__(self):
 3         pass
 4     @property
 5     def start(self):
 6         return 1
 7     @property
 8     def end(self):
 9         return 2
10 
11 obj = Foo()
12 print(obj.start)
13 print(obj.end)

总结:属性编写时,方法上面写@property,方法中只有一个参数self

  调用时,无需加括号,直接是对象.方法

  对于简单的方法,当无需传参且有返回值时,可以使用属性

 

类的定义

class class_name(object):
    attr_name = value #类的公有属性,静态字段
    def __init(self,参数1,参数2...):#构造函数,初始化实例时执行
        self.name = 参数1
        ...#类的属性,成员属性,普通字段

    def func(self,参数1,参数2...):#类的方法
        pass

    def __del__(self):#析构函数,实例销毁时执行
        pass

  字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同.

嵌套(组合):

 1 class Student(object):
 2     def __init__(self,name,age)
 3         self.name = name
 4         self.age = age
 5 #创建三个人
 6 obj1= Student("a",18)
 7 obj2= Student("b",20)
 8 obj3= Student("c",21)
 9 
10 class School(object):
11     def __init__(self,name,address)
12         self.name = name
13         self.address = address
14 
15 #创建三个学校
16 s1 = School("学校1","北京")
17 s2 = School("学校2","上海")
18 s3 = School("学校3","深圳")
19 
20 
21 #给每个学生分配学校
22 obj1.school = s1
23 obj2.school = s2
24 obj3.school = s3
25 
26 print(obj1.school.name)
27 print(obj2.school.name)
28 print(obj3.school.name)

 

类的实例化

var1 = class_name(参数1,参数2...)#这里传入构造函数中形参的实参

  普通字段属于对象

类的私有属性

self.__attrname用两个下划线开头定义为私有属性,只在类的内部可以访问

  静态字段属于类

class Foo:    #类变量    country = "你好"    def __init__(self,name):        # 实例变量        self.name = name    def too:        print("===========")#直接访问普通字段obj = Foo("李白")obj.too()#直接访问静态字段print(Foo.country)

只读访问私有属性

  • 在类中定义一个方法返回此属性,对外部提供只读访问接口

    def get_attrname(self)
    return self.__attrname
    
  • 强制访问(不要这么做)
    实例后跟‘.’,接一个下划线,接类名,接两个下划线的私有属性

    var1 = class_name()
    var1._class_name__attrname
    

  由上述代码可以看出[普通字段需要通过对象来访问] [静态字段通过类访问],在使用上可以看出普通字段和静态字段的归属是不同的,其在内容的存储方式也不一样,静态字段在内存中只保存一份,普通字段在每个对象中都要保存一份

类的公有属性

var1 = class_name(参数1,参数2)
var2 = class_name(参数1,参数2)
#上文定义类中,var1.name和var2.name是根据实例化时传入的参数1而不同,因此叫做成员属性
#上文中在__init__前定义的attr_name则是公有属性,由每个实例共享

#更改类的公有属性
var1.attr_name = new_value#通过实例去修改,修改的是实例自己的公有属性
#此时print(var1.attr_name)  值发生改变,print(var2.attr_name)  值未改变

class_name.attr_name = new_value#通过类更改,修改的是所有以这个类实例化的对象的公有属性
#此时print(var1.attr_name)  ,print(var2.attr_name)  值均已改变,且均为new_value

  上面我们看到的两种字段都是公有字段,下面为私有字段

class Foo:    #类变量    country = "你好"    #私有类变量    __ctorens = "再见"    def __init__(self,name,phone):        # 实例变量        self.name = name        #私有示例变量        self.__phone = phone    def too:        print(Foo.__ctorens)#直接访问普通字段obj = Foo("李白","165136851546")obj.too()#直接访问静态字段print(Foo.country)#在类外面是没法访问类中的私有字段的,所以这里会报错print(Foo.ctorens)

图片 1

面向对象编程(OOP)语言的一个主要功能就是【继承】

  • 继承是指使用现有类的所有功能,无需编写原来的类而进行这些功能的扩展
  • 通过继承创建的新类称为【子类】或【派生类】
  • 被继承的类称为【父类】、【基类】或【超类】
  • 继承可以通过【继承】(Inheritance)和【组合】(Composition)来实现
  • 在某些OOP语言中,一个子类可以继承多个基类。但一般情况下,一个子类只继承一个基类,要实现多重继承,可以通过多级继承来实现。

二丶方法

继承的实现方式有两种

  • 实现继承
  • 使用基类的属性方法无需额外编码
  • 接口继承
  • 仅使用基类的属性和方法名称,但子类必须重构基类方法

  方法包括普通方法丶静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同

在考虑使用继承时,需要注意两个类之间应该是【属于】关系


  1.普通方法:由对象调用,至少一个self参数,执行普通方法时,自动将调用该方法的对象赋值给self

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website