文章目录
- 1 Python面向对象
- 1.1 面向对象技术简介
- 1.2 类的定义
- 1.3 创建对象——类的实例化
- 1.4 类的方法
- 1.5 继承
- 1.5.1 单继承
- 1.5.2 多继承
- 1.6 方法重写
- 1.7 类属性与方法
- 1.7.1 类的私有属性
- 1.7.2 类的方法
- 1.7.3 类的私有方法
- 2 C++面向对象
- 3 参考文献
1 Python面向对象
1.1 面向对象技术简介
下面是面向对象的一些术语:
1、类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。
2、方法:类中定义的函数。
3、类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。
4、数据成员:用于处理类及其实例对象的相关数据。
5、方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法重写。
6、局部变量:定义在方法中的变量,只作用于当前实例的类。
7、实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量。Python中的实例变量就是一个用self修饰的变量。
8、继承:即一个派生类(derived class)继承基类(base class)的字段和方法。
9、实例化:创建一个类的实例,即类的具体对象。
10、对象:通过类定义的数据结构的实例。对象包括两类数据成员——变量和方法,其中变量包括类变量和实例变量。
个人觉得这些概念比较重要,但是没必要纠结具体的说法。
在Python中,允许:
1、派生类继承自多个基类;
2、派生类覆盖基类中的任何方法;
3、派生类中的方法调用基类中的同名方法;
4、对象可以包含任意数量和类型的数据。
1.2 类的定义
语法格式如下:
class classname:
语句体
...
上述代码定义了一个classname类,未继承自任何(父)类。
1.3 创建对象——类的实例化
属性引用语法:obj.name。
class MyClass:
i=1
def f(self):
return 'naruto'
x=MyClass() #类的实例化
print('MyClass的属性i为:',x.i)
print('MyClass的方法f的输出为:',x.f())
输出为:
MyClass的属性i为: 1
MyClass的方法f的输出为: naruto
类有一个名为__init__()
的特殊方法,称为构造函数,如:
def __init__(self):
self.data=1
若类定义了__init__()
方法,在实例化操作时会自动调用__init__()
方法。如下:
x=MyClass()
执行上述代码会得到类MyClass的一个实例,并将该对象赋值给变量x,在此过程中对应的__init__()
方法就会被调用。
__init__()
方法可以有除self以外的其他参数,但是必须排在self后面。参数通过__init__()
传递到类的实例化操作上。例如:
class Complex:
def __init__(self,realpart,imagpart):
self.r=realpart
self.i=imagpart
x=Complex(3,2)
print(x.r,x.i)
输出如下:
3 2
注意,self代表类的实例,而非类。类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照Python语法,其名称是self。
class Test:
def prt(self):
print(self)
print(self.__class__)
t=Test()
t.prt()
输出如下:
<__main__.Test object at 0x000001D6F6241550>
<class '__main__.Test'>
从执行结果来看,self代表的是类的实例,代表当前对象的地址,而self.class指向的是类。
1.4 类的方法
在类的内部,使用def关键字定义一个方法,类方法的第一个参数必须是self,代表的是类的实例。
class people:
def __init__(self,n,a):
self.name=n
self.age=a
def speak(self):
print('%s说自己%d岁了'%(self.name,self.age))
p=people('naruto',18)
p.speak()
输出如下:
naruto说自己18岁了
1.5 继承
1.5.1 单继承
派生类的定义如下所示:
class Dclassname(Basename):
语句体
...
子类会继承父类的属性和方法。除了类,还可以用表达式——当基类定义在另一个模块中时这一点非常有用:
class Dclassname(modulename.Basename):
语句体
...
下面是示例代码片段:
class people:
def __init__(self,n,a):
self.name=n
self.age=a
def speak(self):
print('%s说自己%d岁了'%(self.name,self.age))
class student(people):
def __init__(self,n,a,g):
people.__init__(self,n,a) #调用父类的构造函数
self.grade=g
def speak(self): #重写父类方法
print('%s说自己%d岁了,且在读%d年级'%(self.name,self.age,self.grade))
s=student('naruto',18,10)
s.speak()
输出如下:
naruto说自己18岁了,且在读10年级
1.5.2 多继承
Python支持多继承,多继承的类定义如下:
class Dclassname(Base1,Base2,...):
语句体
...
注意圆括号中多个父类的先后顺序:若是多个父类中有相同方法名的方法,而在子类使用时又未指定使用哪一个,python就会从左至右搜索,调用查找到的父类中的第一个相同方法名的方法。
class people:
def __init__(self,n,a):
self.name=n
self.age=a
def speak(self):
print('%s说自己%d岁了'%(self.name,self.age))
class student(people): #people的子类
def __init__(self,n,a,g):
people.__init__(self,n,a) #调用父类的构造函数
self.grade=g
def speak(self):
print('%s说自己%d岁了,且在读%d年级'%(self.name,self.age,self.grade))
class speaker(): #另外定义的一个类
def __init__(self,n,t):
self.name=n
self.topic=t
def speak(self):
print('%s演讲的题目是%s'%(self.name,self.topic))
class sample(speaker,student): #多继承
def __init__(self,n,a,g,t):
student.__init__(self,n,a,g)
speaker.__init__(self,n,t)
test=sample('naruto',18,10,'Python')
test.speak() #方法名相同时,默认调用的是在括号中排在前的父类的方法
输出如下:
naruto演讲的题目是Python
1.6 方法重写
如果父类方法不能满足需求,可在子类重写父类方法,实例如下:
class Parent:
def myMethod(self):
print('调用父类方法')
class Child(Parent):
def myMethod(self):
print('调用子类方法')
c=Child()
c.myMethod()
输出如下:
调用子类方法
1.7 类属性与方法
1.7.1 类的私有属性
__private_attrs
:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs
。
1.7.2 类的方法
在类的内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数,self代表的是类的实例。
1.7.3 类的私有方法
__private_method
:两个下划线开头,声明该方法为私有方法,只能在类的内部调用,不能在类的外部调用。在类内部中使用时self.__private_methods。
类的私有属性实例如下:
class JustCounter:
__secretCount=0
publicCount=0
def count(self):
self.__secretCount+=1
self.publicCount+=1
print(self.__secretCount)
counter=JustCounter()
counter.count()
print(counter.publicCount)
try:
print(counter.__secretCount) #会报错
except AttributeError:
print('出现AttributeError!')
输出如下:
1
1
出现AttributeError!
类的私有方法实例如下:
class Site:
def __init__(self,name,url):
self.name=name
self.__url=url
def who(self):
print('name:',self.name)
print('url:',self.__url)
def __foo(self): #私有方法
print('这是私有方法')
def foo(self): #公有方法
print('这是公有方法')
self.__foo()
x=Site('CSDN','https://blog.csdn.net/qq_40061206')
x.who()
x.foo()
try:
x.__foo()
except AttributeError:
print('出现AttributeError!')
生成如下:
name: CSDN
url: https://blog.csdn.net/qq_40061206
这是公有方法
这是私有方法
出现AttributeError!
2 C++面向对象
继承允许依据一个类来定义另一个类,这使得创建和维护一个程序变得更容易,也达到了重用代码功能和提高执行效率的效果。当创建一个类时,不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。已有的类称为基类,新建的类称为派生类或子类。继承代表了is a
关系,例如:哺乳动物是动物,狗是哺乳动物等。
C++允许子类派生自多个父类,即可从多个基类继承其数据和函数。定义派生类时,使用一个类派生列表来指定基类——类派生列表以一个或多个基类命名,形式如下:
class derived-class:access-specifier base-class
其中,访问修饰符access-specifier是public、protected或private其中的一个,base-class是父类的名称。如果未使用访问修饰符access-specifier,则默认为private。举个栗子,假设有一个基类Shape,Rectangle是它的派生类,如下所示:
#include<iostream>
using namespace std;
class Shape{
public:
void setWidth(int w){
width=w;
}
void setHeight(int h){
height=h;
}
protected:
int width;
int height;
};
class Rectangle:public Shape{
public:
int getArea(){
return width*height;
}
};
int main(){
Rectangle Rect;
Rect.setHeight(7);
Rect.setWidth(5);
cout<<"面积为:"<<Rect.getArea()<<endl;
return 0;
}
输出如下:
面积为:35
派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为private。根据访问权限总结出三种访问类型,如下:
访问 | public | protected | private |
同一个类 | yes | yes | yes |
派生类 | yes | yes | no |
外部的类 | yes | no | no |
派生类会继承除下面三种情况以外的所有的基类方法:
1、基类的构造函数、析构函数和拷贝构造函数。
2、基类的重载运算符。
3、基类的友元函数。类的友元函数是定义在类外部,但有权访问类的所有private成员和protected成员的函数。友元可以是一个函数,则该函数被称为友元函数;友元也可以是一个类,则该类被称为友元类,在这种情况下,整个类及其所有成员都是友元,即都有权访问类的所有private成员和protected成员的函数和变量。
当一个类派生自基类,该基类可以被继承为public、protected或private共3种类型。继承类型是通过访问修饰符access-specifier指定的。一般不使用protected或private继承,通常使用public继承。当使用不同类型的继承时,遵循以下3个规则:
1、公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来间接访问基类的私有成员。
2、保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
3、私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
多继承即一个子类可以有多个父类,它继承了多个父类的特性。C++语法如下:
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…{
<派生类类体>
};
其中,访问修饰符继承方式是public、protected或private其中的一个,用来修饰每个基类,各个基类之间用逗号分隔。
3 参考文献
1、Python对象。
2、C++继承。
END