JAVA继承:
继承的概念:
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域,属性,和方法,使得子类具有和父类相同的行为。
生活中举例子:
为什么要继承
比如现在有两个类,老虎类和狮子类,老虎类和狮子类中都包括eat(),sleep(),和run()这些方法,可以看出代码重复存在,导致代码臃肿,维护性也不高,修改的时候需要更改更多的代码,所以可以想到如果有一个公共的模块就可以很方便,继承便实现了,从两段代码中取出来一个共同的部分组成父类。
继承怎们书写:
格式:
class 父类{
}
class 子类 extends 父类{
}
例如
父类:
class animals{
void eat(){
System.out.printIn("吃东西");
}
void sleep(){
System.out.printIn("睡觉")
}
}
子类:
class laohu{
void eat(){
System.out.printIn("老虎在吃东西")
}
public class Test{
public static void main(String [] args){
Animals animals = new Animals();
animals.eat();
laohu lao = new laohu();
lao.eat();//此时调用子类中的eat(),如果父类和子类有同一个方法,调用子类的方法;
Animals a = new Animals();
a.eat();//调用父类的方法;
}
}
}
上述案例中说明类的多态,类的多态可以根据引用指向的是子类还是父类来调用子类还是父类的方法.
class A
{
void r(){}
}
class B extends A
{
@override
void r(){}
}
A x;
当x=new A()时,x.r()调用的就是A中的r()
当x=new B()时,x.r()调用的就是B中的r()
我刚开始疑惑为什么父类不能调用子类的方法,父类一开始是不能确定子类,这样不符合逻辑,也没有一点X用,试想父亲把自己的特征遗传给儿子,教会儿子方法,子类继承了父类,父亲要学习儿子的方法显然是不合理的,如果一定要调用子类,那为什么要继承它呢?搞不懂。其实这个问题可以换个角度去理解,父类建立框架,子类在重写了父类部分的方法后,再调用从父类继承的方法,产生不同的结果(而这正是模板方法模式)。这是不是也可以理解为父类调用了子类的方法呢?你修改了子类,影响了父类行为的结果,曲线救国的方式实现了父类依赖子类的场景,模板方法模式就是这种效果。
怎么做?
● 把子类传递到父类的有参构造中,然后调用。
● 使用反射的方式调用,你使用了反射还有谁不能调用的?!
● 父类调用子类的静态方法。
继承类型
java继承不支持多继承,一个子类只能有一个父类,但是一个父类可以有多个子类,可以多重继承。
继承的特征:
-
子类拥有父类非 private 的属性、方法。
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法。
-
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
-
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
super 与 this 关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
实例
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
结果:
animal : eat
dog : eat
animal : eat
final关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
声明类:
final class 类名{}
声明方法:
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
子类不能直接继承父类中的 private 属性和方法,子类能继承父类的所有属性,但父类的私有属性,子类只是拥有,无法使用。
/**建立一个公共动物父类*/
public class Animal {
private String name;
private int id;
/*由于name和id都是私有的,所以子类不能直接继承,
需要通过有参构造函数进行继承*/
public Animal(String myname,int myid) {
name = myname;
id = myid;
}
public void eat() {
System.out.println(name+"正在吃");
}
public void sleep() {
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" +id+"号"+name +".");
}
}
//子类中要用super声明,不然会报错
public class Penguin extends Animal {
public Penguin(String myname,int myid) {
super(myname,myid); // 声明继承父类中的两个属性
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Penguin QQ = new Penguin("小冰",10086);
//调用一个有参构造方法
QQ.eat();
QQ.sleep();
QQ.introduction();
}
}
输出结果:
小冰正在吃
小冰正在睡
大家好!我是10086号小冰.
下面一张图觉得有意思