在面向对象程序设计中,可以从已有的类派生出新类。 这称做继承(inheritance)。
白话解释:
例子1:继承一般是指晚辈从父辈那里继承财产,也可以说是子女拥有父母给予他们的东西。
例子2:猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物。同理,咖啡猫和波斯猫继承自猫,而泰迪犬和比特犬继承自狗。所有的动物之间都会形成一个继承体系,具体下图:
所不同的是,这里继承的实体是类而非人.事物,也就是说。继承是子类拥有父类的成员。
当一个类继承自另一个类时候,我们会说这是子类去继承父类。若你想知道某物是否应该要继承另一物时,则可以用IS-A测试来检验。
三角形是一个多边形……没错。
妇科医生是一个医生……也没错。
泰迪是一只狗……对。
澡盆是一个浴室……错。
排骨没有洗干净……这是在说什么?
以后开发的时候如果想知道设计有没有错误,适用这样的测试来加以检验。如果不合理,表示你的设计有问题。
浴室和澡盆确实有关联,但不是继承关系。浴室与澡盆发生的是HAS-A的关系。如果“浴室有一个澡盆”成立的话,这表示浴室带有澡盆的实例变量。也就是说浴室会有个澡盆的引用,但是浴室并没有继承过澡盆。
继承特点
1:描述类和类之间的关系
2:降低类和类之间的重复代码
1:降低对象和对象之间的代码重复使用静态变量
2:降低类和类之间的代码重复使用就继承
测试代码1(dog类和cat类都继承Animal类):
package day08; //定义Animal类 class Animal{ String name ; //定义动物叫的方法 void shout(){ System.out.println(this.name+"在叫"); } } //定义Dog类继承Animal类 class Dog extends Animal{ public void dogName(){ //定义一个打印name的方法 System.out.println("name="+this.name); } } class Cat extends Animal{ //定义一个打印name的方法 public void catName(){ System.out.println("name="+this.name); } } public class Demo1 { public static void main(String[] args){ Dog dog = new Dog();//创建一个Dog类的实例对象 dog.name = "哈士奇" ;//为Dog类的name属性进行赋值 dog.dogName();//调用Dog类的dogName()方法 dog.shout();//调用Dog类的shout()方法 Cat cat = new Cat();//创建一个Cat类的实例对象 cat.name = "波斯猫" ;//为Cat类的name属性进行赋值 cat.catName();//调用Cat类的catName()方法 cat.shout();//调用Cat类的shout()方法 } }运行结果:
测试代码1中的Dog类通过extends关键字继承了Animal类,这样Dog类便是Animal类的子类。从运行结果我们可以看出,dog类和cat类(子类)虽然没有定义name属性和shout()方法,但是却能访问这两个成员。这就说明,子类继承父类的时候,会自动拥有父类所有的成员。
在类的继承中,需要注意一些问题:
1.在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类,例如下面测试代码2这就不合法了
测试代码2(类不允许多继承):
class A{} class B{} class C extends A,B{} //C类不能同时继承A类和B类。。
2.多个类可以继承一个父类,例如下面测试代码3这种情况是允许的
测试代码3(多个类可以继承一个父类):
class A{} //B类和C类都可以继承A类 class B extends A{} class C extends A{}
3.在Java中,多层继承是允许的,即一个类的父类可以再去继承另一个的父类, 例如C类继承自B类,而B类又可以去继承A类,这是,C类可称作A类的子类。 在Java中,子类和父类是一种相对概念,也就是说一个类是某个类的父类同时,也可以是另一个类的子类。B类是A类的子类,同时又是C类的父类,下面测试代码4这种情况是允许的。
测试代码4(C继承B,B继承A):
class A{} //A类是B类和C类的父类 class B extends A{} //B类继承A类,B类是A类的子类 class C extends B{} //C类继承B类,C类是B类的子类,同时也是A类的子类。
继承细节;
一:类名的设定,被继承的类称之为父类(基类),继承的类称之为子类
二:子类并不能继承父类中所有的成员
1:父类定义完整的成员 静态成员,非静态,构造方法。静态变量和静态方
法都可以通过子类名.父类静态成员的形式调用成功。
2:所有的私有成员不能继承,private修饰的成员。
3:构造函数不能被继承
三:如何使用继承
1:不要为了使用继承而继承。工人和学生都有共性的成员,不要为了节省代
码,让工人继承学生。
在继承关系中,子类会自动继承父类中定义的方法,但是有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。
重写的方法需要和父类被重写的方法具有相同的方法名,参数列表以及返回值类型。
Cat_1类从Animal类继承了shout()方法,该方法在调用的时候会打印"动物在叫",这是明显不能明确描述哪种动物在叫,Cat类对象表示猫科动物,应该发出的叫声是“喵喵”,为了解决这问题,我可以在Cat_1类中重写父类Animal_1中的shout()方法。
测试代码5(重写父类shout()方法):
package day08; //定义Animal类 class Animal_1{ String name ; //定义动物叫的方法 void shout(){ System.out.println("动物在叫"); } } class Cat_1 extends Animal_1{ //定义一个打印name的方法 void shout(){ System.out.println("喵喵"); } } public class Demo2 { public static void main(String[] args){ Cat_1 cat = new Cat_1(); cat.shout(); } }运行结果:
测试代码5Cat_1类继承了Animal_1类。 从结果可以看出,在调用Cat_1类对象的shout()方法时,只会调用子类从写重写的该方法,并不会调用父类的shout()方法。
P.S.
子类在重写父类的方法时,不能使用比父类中被重写的方法更严格的访问权限,如果父类中的方法时public的,子类的方法就不能是private的,关于访问权限中的更多问题,在我以后的blog中我会详细讲出,这里有个印象就可以了。
联系企鹅:654249738