1、定义
继承:子类可以获得父类的public方法,程序使用子类时,将可以直接访问该子类从父类那里继承到的方法。
组合:把旧类的对象作为新类的成员变量组合进行,用以实现新类的功能,用户看到的是新类的方法,而不能看到 被组合对象的方法
2、相同点与不同点
相同点:都是实现类复用的重要手段
不同点:继承可使变量具有多态性、组合则不具备这种多态的灵活性
继承会破坏父类的封装性、组合则不会
3、举例
适合使用继承的例子:
//使用继承手段:
class Person{
private void beat() {
System.out.println("人的心会跳");
}
public void breath() {
beat(); //人在呼吸的时候心会跳,所以调用beat方法
System.out.println("人会呼吸");
}
}
//继承Person类,直接拥有父类的breath方法,因为beat方法是private修饰的,因此不可以直接调用beat方法
class Student extends Person{
public void studying() {
System.out.println("学生需要学习");
}
}
//继承Person类,直接拥有父类的breath方法,因为beat方法是private修饰的,因此不可以直接调用beat方法
class Teacher extends Person{
public void teaching() {
System.out.println("老师会传授知识");
}
}
public class t{
public static void main(String[] args) {
Student s=new Student();
s.breath();
s.studying();
Teacher t=new Teacher();
t.breath();
t.teaching();
}
}
//使用组合手段:
class Person{
private void beat() {
System.out.println("人的心会跳");
}
public void breath() {
beat(); //人在呼吸的时候心会跳,所以调用beat方法
System.out.println("人会呼吸");
}
}
class Student{
//将原来父类组合到原来的子类,作为子类的一个组合成分
private Person p; //定义一个Person类的实例p,则该实例p可以访问Person类中的breath方法
//定义Student类的构造器
public Student(Person p) {
this.p=p;
}
//Student类中的breath方法
public void breath() {
p.breath(); //访问到Person类的breath方法
}
public void studying() {
System.out.println("学生需要学习");
}
}
class Teacher{
//将原来父类组合到原来的子类,作为子类的一个组合成分
private Person p;//定义一个Person类的实例p,则该实例p可以访问Person类中的breath方法
//定义Teacher类的构造器
public Teacher(Person p) {
this.p=p;
}
//Teacher类中的breath方法
public void breath() {
p.breath();
}
public void teaching() {
System.out.println("老师会传授知识");
}
}
public class t{
public static void main(String[] args) {
Person p1=new Person(); //需要显示创建一个被组合的Person对象
Student s=new Student(p1);
s.breath();
s.studying();
Person p2=new Person();//需要显示创建一个被组合的Person对象
Teacher t=new Teacher(p2);
t.breath();
t.teaching();
}
}
/*对于Student和Teacher两个类来说,他们都会breath,并且这个breath与父类的breath方法完全相同。但是这里无法直接访问Person类的breath方法,因此需要在新类中创建一个Person对象,利用该对象来访问父类的breath方法。*/
输出结果:
人的心会跳
人会呼吸
学生需要学习
人的心会跳
人会呼吸
老师会传授知识
适合使用组合的例子:
//采用继承方式
class School{
private void Location() {
System.out.println("学校的地点");
}
public void Name() {
Location(); //不同的学校名字会有不同的地点
System.out.println("学校的名字");
}
}
//继承School类,直接拥有父类的Name方法
class Student extends School{
public void studying() {
System.out.println("学生需要学习");
}
}
//继承School类,直接拥有父类的Name方法
class Teacher extends School{
public void teaching() {
System.out.println("老师会传授知识");
}
}
public class t{
public static void main(String[] args) {
Student s=new Student();
s.Name();
s.studying();
Teacher t=new Teacher();
t.Name();
t.teaching();
}
}
//采用组合方式
class Student{
private School sch;
public Student(School sch) {
this.sch=sch;
}
public void Name() {
sch.Name();
}
public void studying() {
System.out.println("学生需要学习");
}
}
class Teacher{
private School sch;
public Teacher(School sch) {
this.sch=sch;
}
public void Name() {
sch.Name();
}
public void teaching() {
System.out.println("老师会传授知识");
}
}
public class t{
public static void main(String[] args) {
School sch1=new School();
Student s=new Student(sch1);
s.Name();
s.studying();
School sch2=new School();
Teacher t=new Teacher(sch2);
t.Name();
t.teaching();
}
}
/*输出结果:
学校的地点
学校的名字
学生需要学习
学校的地点
学校的名字
老师会传授知识
*/
4、总结
继承是一种”是(is-a)“的关系,比如上面的”l老师是人类“、”学生是人类“
组合是一种“有(has-a)”的关系,比如上面的“老师有学校的不同”、“学生有学校的不同”