python基础编程——类和实例
在了解类和实例之前,需要先了解什么是面向对象,什么又是面向过程。面向过程是以过程为中心实现一步步操作(相互调用,类似流水线思想);面向对象是以事物为中心,某个事物可以拥有自己的多个行为,而另一个事物也可以拥有自己的多个行为。
面向对象的基础:
对象:没有具体的事物,只能说是一切皆对象。如人、汽车、国家,.......
对象的属性和行为:这个对象有什么特征或者有什么行为方式。如人有身高、头发颜色等属性,人有睡觉、吃饭等行为
类:将具有相同特征的属性和行为的对象抽象出来封装成一个可以描述多个对象的类。所以就有类是对象的抽象,对象是类的实例
消息和方法:对象之间的通信传递简称消息,而方法是实现传递消息的可观效果
继承:某个对象是由另一个对象产生的,也可以抽象为某个类是由另一个类产生的,这个对象就可以拥有另个对象的所有属性和行为
多态:多个对象的相同行为会产生不一样的结果
面向对象的特性:
由上述我们可以总结出抽象、封装、继承、多态4大特性
本篇博客主要内容就是简单的讲述这4大特性和面向对象的基础知识,在讲述的过程中会扩展一些知识
抽象
类是软件开发过程中对业务相关的具有共同特征的事物的抽象。所以类在编程语言中是抽象的主要表现形式
我们可以对“人”进行抽象并抽象成Person类,因为人类有一些共同的特征,我们也可以对“动物”进行抽象并抽象成Animal类。
# Person类 class Person: """ 人的共有特征和行为 """ def __init__(self, high, weight): self.high = high self.weight = weight # 说话 def speak(self): pass # 睡觉 def sleep(self): pass
代码博主只写了一丢丢Person共有的属性和行为,有过编程经验的朋友们都知道一些初始化方法,这里是初始化一些共有的属性;还定义一些共有的方法;
在接下来讲的应该都是封装需要讲述的
封装
对于封装,类可以封装我们上述所说的具有共同属性和行为的一种方式(大的封装)。而封装又不限于类,函数也是可以封装一些共同的操作。下面涉及的知识都是封装,只是封装的方式会略有不同,我们先不谈封装知识。
我们先对初始化方法进行一个简单的了解,python类里__init__()方法是对对象的初始化一些属性的方法,但是这个方法不是创建对象。我们在创建类时,这个__init__()方法就是我们需要放置一些我们考虑多个对象的共同的属性还有一些需要初始化的操作(调用方法),既然__init__()方法不是创建对象的方法,那么创建对象的方法是哪个呢?__new__()方法。相信朋友们已经见过了这个方法,这个方法在创建类时会自动调用,不需要我们写出来(待会写出来用于测试)。这样明了,创建对象的时候先调用__new__()方法返回一个对象,然后再调用__init__()方法初始化对象的属性。
class Person: def __new__(cls, *args, **kwargs): # 父类调用__new__()返回一个对象 return super().__new__(cls) def __init__(self, high, weight): self.high = high self.weight = weight person = Person(12, 135)
在类中可以有很多属性,我这说的很多不是属性的个数,也不是属性值的类型,而是属性的类型。以下代码里的注释可以忽略
属性的类型有:类属性、类的私有属性、类的保护属性,实例属性、实例的私有属性、实例的保护属性,这里说的保护属性和私有属性,在python中没有严格说明,但是功能或者使用保留
1、类属性:
类和实例都可以直接修改并且访问类属性
在实例方法通过实例访问和修改类属性
在类方法通过类名访问和修改类属性
在静态方法通过类名访问和修改类的私属性
如果实例有与类属性同名的实例属性,那么修改和访问就和类属性没有关系了
class Person: # 类的保护属性初始值“12” count = "12" def __init__(self, high, weight): self.high = high self.weight = weight def self_set_count(self, count): self.count = count def self_get_count(self): return self.count # 类方法 @classmethod def class_set_count(cls, count): cls.count = count @classmethod def class_get_count(cls): return cls.count # 静态方法 @staticmethod def static_set_count(count): Person.count = count @staticmethod def static_get_count(): return Person.count person = Person(12, 135) # 实例直接修改并访问类的保护属性 person.count = "24" print(person.count) # 类名直接修改并访问类的保护属性 Person.count = "36" print(Person.count) # 实例调用实例方法修改并访问类的私有属性 person.self_set_count("24") print(person.self_get_count()) # 24 # 类名调用类方法修改并访问类的私有属性 Person.class_set_count("36") print(Person.class_get_count()) # 36 # 实例调用静态方法修改并访问类的私有属性 person.static_set_count("24") print(person.static_get_count()) # 24 # 类名调用静态方法修改并访问类的私有属性 Person.static_set_count("36") print(Person.static_get_count()) # 36
2、类的私有属性:
在实例方法通过实例访问和修改类的私有属性
在类方法通过类名访问和修改类的私有属性
在静态方法通过类名访问和修改类的私有属性
在类外类和实例都是不能访问的;如果实例有与类的私有属性同名的实例私有属性,那么修改和访问就和类的私有属性没有关系了
class Person: # 类属性初始值12 count = 12 # 类的私有属性初始值“12” __string = "12" def __new__(cls, *args, **kwargs): return super().__new__(cls) def __init__(self, high, weight): self.high = high self.weight = weight def self_set_string(self, string): self.__string = string def self_get_string(self): return self.__string # 类方法 @classmethod def class_set_string(cls, string): cls.__string = string @classmethod def class_get_string(cls): return cls.__string #静态方法 @staticmethod def static_set_string(string): Person.__string = string @staticmethod def static_get_string(): return Person.__string person = Person(12, 135) # 实例修改并访问类属性 person.count = 24 print(person.count) # 24 # 类名修改并访问类属性 Person.count = 36 print(Person.count) # 36 # 实例调用实例方法修改并访问类的私有属性 person.self_set_string("24") print(person.self_get_string()) # 24 # 类名调用类方法修改并访问类的私有属性 Person.class_set_string("36") print(Person.class_get_string()) # 36 # 实例调用静态方法修改并访问类的私有属性 person.static_set_string("24") print(person.static_get_string()) # 24 # 类名调用静态方法修改并访问类的私有属性 Person.static_set_string("36") print(Person.static_get_string()) # 36
3、类的保护属性:
在类外通过类和实例访问和修改类的保护属性
在实例方法通过实例访问和修改类的保护属性
在类方法通过类名访问和修改类的保护属性
在静态方法通过类名访问和修改类的保护属性
在模块外类和实例都是不能访问的;如果实例有与类的保护属性同名的实例保护属性,那么修改和访问就和类的保护属性没有关系了
class Person: # 类的保护属性初始值“12” _protection = "12" def __init__(self, high, weight): self.high = high self.weight = weight def self_set_protection(self, protection): self._protection = protection def self_get_protection(self): return self._protection # 类方法 @classmethod def class_set_protection(cls, protection): cls._protection = protection @classmethod def class_get_protection(cls): return cls._protection #静态方法 @staticmethod def static_set_protection(protection): Person._protection = protection @staticmethod def static_get_protection(): return Person._protection person = Person(12, 135) # 实例直接修改并访问类的保护属性 person._protection = "24" print(person._protection) # 类名直接修改并访问类的保护属性 Person._protection = "36" print(Person._protection) # 实例调用实例方法修改并访问类的私有属性 person.self_set_protection("24") print(person.self_get_protection()) # 24 # 类名调用类方法修改并访问类的私有属性 Person.class_set_protection("36") print(Person.class_get_protection()) # 36 # 实例调用静态方法修改并访问类的私有属性 person.static_set_protection("24") print(person.static_get_protection()) # 24 # 类名调用静态方法修改并访问类的私有属性 Person.static_set_protection("36") print(Person.static_get_protection()) # 36
4、实例属性:
在类外通过类和实例访问和修改实例属性
在实例方法通过实例访问和修改实例属性
在类方法通过类名访问和修改实例属性
在静态方法通过类名访问和修改实例属性
如果实例有与类属性同名的实例属性,那么修改和访问就和类属性没有关系了
class Person: def __init__(self, high, weight): # 实例属性 self.high = high self.weight = weight def self_set_high(self, high): self.high = high def self_get_high(self): return self.high # 类方法 @classmethod def class_set_high(cls, high): cls.high = high @classmethod def class_get_high(cls): return cls.high # 静态方法 @staticmethod def static_set_high(high): Person.high = high @staticmethod def static_get_high(): return Person.high person = Person(12, 135) # 实例直接修改并访问类的保护属性 person.high = "24" print(person.high) # 类名直接修改并访问类的保护属性 Person.high = "36" print(Person.high) # 实例调用实例方法修改并访问类的私有属性 person.self_set_high("24") print(person.self_get_high()) # 24 # 类名调用类方法修改并访问类的私有属性 Person.class_set_high("36") print(Person.class_get_high()) # 36 # 实例调用静态方法修改并访问类的私有属性 person.static_set_high("24") print(person.static_get_high()) # 24 # 类名调用静态方法修改并访问类的私有属性 Person.static_set_high("36") print(Person.static_get_high()) # 36
5、实例的私有属性:
在实例方法通过实例访问和修改实例私有属性
在类方法通过类名访问和修改实例私有属性
在静态方法通过类名访问和修改实例私有属性
在类外通过类和实例访问和修改实例私有属性,相当于自身动态增加了一个属性,所以在类外是不能访问的;如果实例有与类的私有属性同名的实例私有属性,那么修改和访问就和类的私有属性没有关系了
class Person: def __init__(self, high, weight): # 实例属性 self.high = high self.__weight = weight def self_set_weight(self, weight): self.__weight = weight def self_get_weight(self): return self.__weight # 类方法 @classmethod def class_set_weight(cls, weight): cls.__weight = weight @classmethod def class_get_weight(cls): return cls.__weight # 静态方法 @staticmethod def static_set_weight(weight): Person.__weight = weight @staticmethod def static_get_weight(): return Person.__weight person = Person(12, 135) # 这里是实例动态增加的属性 person.__weight = "24" print(person.__weight) # 这里是类名动态增加的属性 Person.__weight = "36" print(Person.__weight) # 实例调用实例方法修改并访问类的私有属性 person.self_set_weight("24") print(person.self_get_weight()) # 24 # 类名调用类方法修改并访问类的私有属性 Person.class_set_weight("36") print(Person.class_get_weight()) # 36 # 实例调用静态方法修改并访问类的私有属性 person.static_set_weight("24") print(person.static_get_weight()) # 24 # 类名调用静态方法修改并访问类的私有属性 Person.static_set_weight("36") print(Person.static_get_weight()) # 36
6、实例的保护属性:
在实例方法通过实例访问和修改实例保护属性
在类方法通过类名访问和修改实例保护属性
在静态方法通过类名访问和修改实例保护属性
在类外通过类和实例访问和修改实例保护属性,相当于自身动态增加了一个属性,所以在类外是不能访问的;如果实例有与类的私有属性同名的实例私有属性,那么修改和访问就和类的私有属性没有关系了
class Person: def __init__(self, high, weight): # 实例属性 self.high = high # 实例保护属性 self._weight = weight def self_set_weight(self, weight): self._weight = weight def self_get_weight(self): return self._weight # 类方法 @classmethod def class_set_weight(cls, weight): cls._weight = weight @classmethod def class_get_weight(cls): return cls._weight # 静态方法 @staticmethod def static_set_weight(weight): Person._weight = weight @staticmethod def static_get_weight(): return Person._weight person = Person(12, 135) # 这里是实例动态增加的属性 person._weight = "24" print(person._weight) # 这里是类名动态增加的属性 Person._weight = "36" print(Person._weight) # 实例调用实例方法修改并访问类的私有属性 person.self_set_weight("24") print(person.self_get_weight()) # 24 # 类名调用类方法修改并访问类的私有属性 Person.class_set_weight("36") print(Person.class_get_weight()) # 36 # 实例调用静态方法修改并访问类的私有属性 person.static_set_weight("24") print(person.static_get_weight()) # 24 # 类名调用静态方法修改并访问类的私有属性 Person.static_set_weight("36") print(Person.static_get_weight()) # 36
关于类里面涉及属性都举例说明了(亲测有效),但是类中出现了几种方法,这个方法也是关键。类的方法类型:类方法、实例方法、静态方法
主要是验证谁可以调用3大方法
上述代码已经验证了实例可以调用实例方法、类名可以调用类方法、类名可以调用静态方法
实例可以调用类方法和静态方法
类名可以调用实例方法,传参必须传递一个具体实例
class Person: def __init__(self, high, weight): # 实例属性 self.high = high # 实例保护属性 self._weight = weight def self_set_weight(self, weight): self._weight = weight def self_get_weight(self): return self._weight # 类方法 @classmethod def class_set_weight(cls, weight): cls._weight = weight @classmethod def class_get_weight(cls): return cls._weight # 静态方法 @staticmethod def static_set_weight(weight): Person._weight = weight @staticmethod def static_get_weight(): return Person._weight person = Person(12, 135) # 实例调用类方法 person.class_set_weight("24") print(person.class_get_weight()) # 24 # 实例调用静态方法 person.static_set_weight("36") print(person.static_get_weight()) # 36 # 类名调用实例方法,第一个参数必须是具体的实例 Person.self_set_weight(person, "24") print(Person.self_get_weight(person)) # 24
总结:
1、对象名可以调用静态方法、实例方法、类方法
2、类名可以调用静态方法、类方法、实例方法,但在调用实例方法时需要将第一个参数self传入,传入的其实是对象本身,不带参数报错
3、实例属性通过实例方法的<self.>进行访问,静态方法和类方法无法访问实例属性
4、类属性通过类方法的<cls.>进行访问,或者在其他函数内部通过<类名.>访问
继承
当子类/子对象和父类/父对象有很多共同之处,但是又有不同之处,这个时候我们就可以使用继承机制。继承父类的属性和行为,其他属性和行为需自己定义。
python用的最多的继承是单继承,当然python也提供多继承的,但是尽可能的不要使用多继承,如果多继承多了的话,编程的思维很容易乱。
类继承需在类名添加括号,在括号里添加父类名称,这还没有实现继承。使用super关键字调用父类的方法,属性可以直接拿来使用。父类可以看作是对子类的共同属性和方法的抽象,将他们封装成我们需要的父类
类继承的几个关键点:
1、子类继承可以继承父类的初始化函数__init__(),但是子类不写初始化函数时,会自动/默认调用父类的初始化函数;子类定义初始化函数,也一定要调用父类初始化函数
这里继承是只能继承父类的类属性,不能继承父类对象的属性,若想也拥有同样的属性,所以才继承父类的初始化函数。
抱歉!改天更新...