练习42 对象和类的区别
类和对象之间的关系,就是is-a,has-a的关系形容。例如鱼,三文鱼是一种鱼(三文鱼is a fish),三文鱼有鳃(三文鱼has a 鳃)。
总结:对象是类实例化后的产物,当然类也是一个对象,Python 中一切皆对象。
代码练习如下:----解答见注释
## Animal is-a object(yes, sort of confusing) look at the extra credit(附加练习)
class Animal(object):
pass
##Dog is-a Animal
class Dog(Animal):
def __init__(self, name):
##Dog has-a name
self.name = name
## Cat is-a Animal
class Cat(Animal):
def __init__(self,name):
##Cat has-a name
self.name = name
##Person is-a object
class Person(object):
def __init__(self, name):
## Person has-a name.
self.name = name
##Person has-a pet of some kind
self.pet = None
##Employee is-a Person
class Employee(Person):
def __init__(self, name, salary):
##?? hmm what is this strange magic?
super(Employee,self).__init__(name) #python2的写法,超类,继承父类属性,不重复描述super().__init(name),Employee has-a name
##Employee has-a salary
self.salary = salary
## Fish is-a object
class Fish(object):
pass
##Salmon is-a Fish.
class Salmon(Fish):
pass
## Halibut is-a Fish.
class Halibut(Fish):
pass
## rover is-a Dog
rover = Dog("Rover")
## Satan is-a Cat
satan = Cat("Satan")
##mary is-a Person
mary = Person("Mary")
##mary has-a pet called satan
mary.pet = satan
## frank is-a Employee, he has-a salary of 120000
frank = Employee("Frank", 120000)
#frank has-a pet, rover is-a pet
frank.pet = rover
##flipper is-a Fish
flipper = Fish()
##crouse is-a Salmon
crouse = Salmon()
##harry is-a Halibut
harry = Halibut()
知识点:
1.super()函数(超类)
作用:子类存在父类相同属性,调用父类的属性。
语法:super(type[, object-or-type])
,type 为类;object-or-type 一般是 self
python3: super().init()
python2: super(Student,self).init()
示例:
不使用super()函数时
#输入:
#创建父类Human
class Human(object):
def __init__(self, name, sex): #人类属性
self.name = name
self.sex = sex
#创建子类
class Student(Human):
def __init__(self, name, sex, score): #学生包含属性,姓名,性别,分数
self.name = name
self.sex = sex
self.score = score
print("child")
student_1 = Student("Rose","female",89)
print(student_1.name)
#输出:
child
Rose
**使用super()函数:**将子类中与父类相同的属性name、sex合并
#使用super()函数
#创建父类Human
class Human(object):
def __init__(self, name, sex): #人类属性
self.name = name
self.sex = sex
#创建子类
class Student(Human):
def __init__(self, name, sex, score): #学生包含属性,姓名,性别,分数
super().__init__(name,sex) #使用super()函数直接调用
self.score = score
print("child")
student_1 = Student("Rose","female",89)
print(student_1.name)
#输出
child
Rose
2.类名(object)——类的继承
使用小写的“object”这个词作为一个类,让你在创建新类时从它继承下来。一个类继承自另一个类,而后者虽然是个类,名字却叫“object”。在定义类的时候,别忘记要从 object 继承。
Python 3 中,类名后的 (object) 可加可不加,无影响。
Python 2 中,加了 (object) 表示定义的类的类型是 object,这是一个基本的简单类。
附加练习
1. 研究一下为什么 Python 添加了这个奇怪的叫做 object 的类,它究竟有什么含义呢?
Python 中一切皆对象(object),object 基类中定义了常用的属性和方法可供使用。
在Python 2 中,若用了object,那定义的类会继承 object 基类的属性和方法;若没用 object,就没有继承。
在Python 3 中,给不给 object 都会默认为继承其属性和方法。
2.有没有可能把一个类当作对象来使用呢?
有可能不将类实例化为对象而调用其中的方法,用 staticmethod() 函数返回类中函数的静态方法从而达到不实例化类而使用其中的方法.
该方法不强制要求传递参数。
语法:
class C(object):
@staticmethod
def f(arg1, arg2, ...):
...
示例如下:
#staticmethod()函数
class C(object):
@staticmethod #静态方法
def f():
print('Hello')
C.f() #静态方法无需实例化
cobj = C()
cobj.f() #也可实例化后调用
输出结果:
Hello
Hello
3.在习题中为 animals、fish、还有 people 添加一些函数,让它们做一些事情。看看当函数在 Animal 这样的“基类(base class)”里和在 Dog 里有什么区别。
具体原来可使用super()函数,可见知识点1。
4.使用列表和字典创建一些新的一对多的“has-many”的关系。-----(不懂)
没找到列表可以一对多处理,字典可以一键对多值。
5.你认为会有一种“has-many”的关系吗?阅读一下关于“多重继承(multiple inheritance)”的资料,然后尽量避免这种用法。
语法:class subClass(Base1,Base2)
创建了一个subClass类,让它同时继承了Base1和Base2的相关特性,关于继承还有以下规则需要遵循:
- 继承只会继承父类的方法,不能继承父类的变量;
- 要想继承父类的变量,需要执行父类的__init__(self)方法;
- 下划线开头的变量或方法,会被认为是受保护的,不能直接点出来,但如果强制打出来的话也一样能用,只是会有警告;
- 静态方法中不能使用self,用@staticmethod声明这是一个静态方法。
示例:
#多重继承,具体使用不会
class A(object):
def __init__(self):
print('A')
super().__init__()
class B(object):
def __init__(self):
print('B')
super().__init__()
class C(A,B):
def __init__(self):
super().__init__()
print("C")
cobj = C()
print(cobj)
输出结果:
A
B
C
<__main__.C object at 0x000001B5B22CC2B0>
常见问题
- self.pet = None有什么意义? 这样确保 self.pet 这个类的属性被设为默认的 None。
- super(Employee, self).init(name) 是干什么的? 这是你运行父类的 init 方法的一种可靠方式。具体见知识点1。