继承:就是一种数据的复制。
为什么要用继承:减少重复代码的编写。
- 下面代码中,Person称为父类,或者基类。
- Teacher.、Student称为子类,或者派生类。
- Tercher t,t称为对象,或者实例。
- 可以使用父类的指针指向子类的对象(但仅仅能访问父类中定义过的数据类型,子类中新增的数据类型不能访问)。
- 反过来,使用子类的指针访问父类的对象是不允许的。
- 子类的构成实际上是先原本的将父类的内容复制一份出来。
假如一个场景:需要定义很多的结构,但是他们的很多成员都是一样的。
struct Person
{
int age;
int sex;
};
struct Teacher
{
int age;
int sex;
int level;
int classid;
};
struct Student
{
int age;
int sex;
int code;
int score;
};
void Test(void)
{
Teacher t;
t.age = 50;
t.classid = 1;
t.level = 2;
t.sex = 3;
}
就像上面代码中,teacher和student都有重复的age和sex,那要定义更多的对象就需要写更多次,为了方便,可以用下面代码的方式写
#include<stdio.h>
#include<malloc.h>
struct Person
{
int age;
int sex;
};
struct Teacher:Person
{
int level;
int classid;
};
struct Student:Person
{
int code;
int score;
};
void Test(void)
{
Teacher t;
t.age = 50;
t.classid = 1;
t.level = 2;
t.sex = 3;
}
int main(int argc,char *argv[])
{
Test();
return 0;
}
子类结构体类型指针访问数据,没有问题,使用父类结构体类型指针访问子类的数据,同样没问题。
void Test(void)
{
Teacher t;
t.age = 50;
t.classid = 1;
t.level = 2;
t.sex = 3;
Teacher *pt = &t;
printf("子类指针访问数据age = %d\n",pt->age);
Person *pp = &t;
printf("父类指针访问数据age = %d\n",pp->age);
}
子类指针访问数据age = 50
父类指针访问数据age = 50
Press any key to continue
多层继承:和继承一样,只是增加了爷爷辈,孙子继承爷爷和父亲的数据。
struct X
{
int a;
int b;
};
struct Y:X
{
int c;
int d;
};
struct Z:Y
{
int e;
int f;
};
void Test()
{
Z z;
printf(" sizeof(z) = %d\n",sizeof(z));
}
如果出现子类的数据和父类重复呢?大小是一模一样的,仍然会分配24个地址空间。
struct X
{
int a;
int b;
};
struct Y:X
{
int a;
int b;
};
struct Z:Y
{
int e;
int f;
};
void Test()
{
Z z;
printf(" sizeof(z) = %d\n",sizeof(z));
}
sizeof(z) = 24
Press any key to continue
但是使用的时候,必须指定是谁的变量。
不重名情况:
Z z;
z.a = 1;
z.b = 2;
z.c = 3;
z.d = 4;
z.e = 5;
z.f = 6;
重名的情况:
Z z;
z.X::a = 1;
z.X::b = 2;
z.Y::a = 3;
z.Y::b = 4;
z.e = 5;
z.f = 6;
多重继承:子类有两个以上父类
出现父类变量重名和多层继承的使用方法一样。
struct X
{
int a;
int b;
};
struct Y
{
int c;
int d;
};
struct Z:X,Y
{
int e;
int f;
};
总结:
- 多重继承增加了程序的复杂程度,容易出错。
- 微软建议使用单继承,如果必须使用多重继承则推荐使用多层继承。
练习:
1.设计一个关于日期的结构DateInfo:一个关于时间的结构TimeInfo,TimeInfo继承DateInfo
#include<stdio.h>
struct DateInfo
{
int year;
int month;
int day;
DateInfo(int year,int month,int day)
{
this->year = year;
this->month = month;
this->day = day;
}
DateInfo()
{
year = 2019;
month = 6;
day = 15;
}
void SetYear(int year)
{
this->year = year;
}
void SetMonth(int month)
{
this->month = month;
}
void SetDay(int day)
{
this->day = day;
}
int GetYear()
{
return year;
}
int GetMonth()
{
return month;
}
int GetDay()
{
return day;
}
void Printf()
{
printf("父类\n");
printf("Year = %d , Month = %d , Day = %d \n",this->year,this->month,this->day);
}
};
struct TimeInfo:DateInfo
{
int hour;
int minute;
int second;
void SetHour(int hour)
{
this->hour = hour;
}
void SetMinute(int minute)
{
this->minute = minute;
}
void SetSecond(int second)
{
this->second = second;
}
int GetHour()
{
return hour;
}
int GetMinute()
{
return minute;
}
int GetSecond()
{
return second;
}
void Printf()
{
printf("子类\n");
printf("hour = %d , minute = %d , second = %d \n",this->hour,this->minute,this->second);
}
};
void test()
{
TimeInfo t;
TimeInfo *pt = &t;
pt->SetYear(2019);
pt->SetMonth(6);
pt->SetDay(15);
pt->SetHour(19);
pt->SetMinute(7);
pt->SetSecond(17);
pt->DateInfo::Printf();
pt->Printf();
}
int main(int argc,char*argv[])
{
test();
getchar();
return 0;
}