JAVA笔记五:继承

一、继承(inheritance)

继承:基于已有类创建新的类,复用(继承)已有类的方法,可以增加一些新的字段与方法。

已存在的类称为:超类(superclass)、基类(base class)、父类(parent class)

新类为:子类(subclass),派生类(derived class)、孩子类(child class)

1、继承(extend):

在Java中,所有继承都是公共继承。使用关键字extend继承父类的所有公共方法与公共字段。

public class Manger extends Employee

{

        add mothdos and fields

}

//子类通过extends关键字继承父类Employee的所有方法

2、覆盖(override)

子类定义的方法名与父类方法重名时,将覆盖父类方法。

覆盖只是对子类的方法进行重写。

实例:Manger.java,Manger类继承Employee类,并定义私有bonus字段以getBonus(),setBonus(),getInfo()等方法

package cn.edu.abc.corejava;
public class Manger extends Employee
{
    private double bonus;
    public Manger(String N, double S, int Year, int month, int day)
    {
        super(N, S, Year, month, day);
    }
    public double getBonus()
    {
        return this.bonus;
    }
    public void setBonus(double bonus)
    {
        this.bonus = bonus;
    }
    public static String getInfo(Manger A[])
    {
        String info="";
        for (Manger e:A)
            info +=e.getName()+"\t"+e.getBonus()+"\n";
        return info;
    }
    public String getName()
    {
        return "管理员:  "+super.getName();
    }
    public static void main(String args[])
    {
        Manger[] boss = new Manger[2];
        boss[0] = new Manger("张某",6000,1999,1,2);
        boss[1] = new Manger("李某",6000,1999,1,2);
        boss[0].setBonus(1000);
        boss[1].setBonus(2000);
        System.out.println(getInfo(boss));
        System.out.println(boss[1].getName());
    }
}

注意:

1、继承为公共继承,可以增加字段、方法或覆盖方法,继承绝对不会删除任何字段与方法。

2、可以利用:super.父类方法,格式调用父类方法。

 public String getName()
    {
        return "管理员:  "+super.getName();
    }

//在Manger子类中定义getName方法覆盖所继承到的父类Employee的getName方法

//super.getName()这条语句调用的是父类Employee的getName方法

    public static String getInfo(Manger A[])
    {
        String info="";
        for (Manger e:A)
            info +=e.getName()+"\t"+e.getBonus()+"\n";
        return info;
    }

//e.getName()为子类的方法

        Employee A = new Employee("员工1",1211,1998,11,1);
        System.out.println(A.getName());
        Manger B = new Manger("管理员1",123,1322,89,88);
        System.out.println(B.getName());

        //覆盖只是对子类的方法进行重写。A.getName()仍旧调用父类Employee的方法

 3、子类构造器

由于Manger类的构造器不能访问Employee的私有字段,所有必须通过super语法调用构造器初始化这些私有字段。super()语句必须是子类构造器的第一条语句。

public class Manger extends Employee
{
    private double bonus;
    public Manger(String N, double S, int Year, int month, int day)
    {
        super(N, S, Year, month, day);
    }

.....

}

关键字this有两个含义:一是指示隐式参数的引用,二是调用该类的其他构造器。

类似的,关键字super有两个含义:一是调用超类的方法,二是调用超类的构造器。

 4、Object类

Object类是所有类的父类,是java中最高层的类,每一个类都扩展了Object,如果没有明确指出父类,Object就被认为是这个类的父类。所有的类都是Object的子类,所有任何类都可以重写Object类中的方法。

<要点>:

        1、可以使用Object类型变量引用任何类型的对象

Object obj = new Employee("管理员",1234,......);

        2、Object类型的变量只能用于作为各种值的一个泛型容器,要对其进行具体的操作还需要清楚其原始的类型,并进行强制转换

Employee e = (Employee)obj;

        3、在Java中只有基本类型不是对象(数值,字符,布尔型),所有的数组类型均为对象。

<方法>:

        1、 equals方法

"=="运算符比较两个对象引用地址是否相等,equals方法比较的是两个对象的实际内容

5、强制类型转换 

向上转型、向下转型、instanceof关键字

向上转型:利用父类描述子类,将一个具体的类转换为一个抽象的类,调用所继承的公共方法,没重写调用没重写的,重写的调用重写的。

Employee Test = new Manger("abc",12,12,1,1);

格式:父类类型 父类对象 = new 子类类型 (即为构造器)

例1、Test调用getName()  ​​​​

 由此可得:调用所继承的公共方法,没重写调用没重写的,重写的调用重写的。

向下转型:父类转化为子类,将抽象的类转化为具体的类,例如:某个员工就是经理

将抽象类的对象转换为具体类的对象是通常是错误的,使用instanceof关键字判断其是否能相互转转换

向下转换:

        Employee Test = new Manger("abc",12,12,1,1);

        Manger  subTest = (Manger) Test;

        前提:父类对象要先引用这个子类对象

        语法格式:子类类型 子类对象 = (子类类型)父类对象

instanceof关键字:

        语法格式myobject instanceof ExampleClass

 例2、subTest 调用子类特有方法setBonus()、getBonus()

Employee Test = new Manger("abc",12,12,1,1);//父类对象引用子类对象
if (Test instanceof Manger)//判断Test是否属于Manger类对象
        {
            Manger subTest = (Manger) Test;//向下转换
            subTest.setBonus(1000);
            System.out.println(subTest.getName()+" "+subTest.getBonus());
        }else
        {
            System.out.println("转换失败");
        }

                                                                                                            

6、阻止继承:final关键字

凡是被final关键字修饰过的内容都是不可被改变的。简称为无法修改,无法重写,无法继承

final字段:在定义时必须赋初值,且使用后无法被修改

final方法:将方法定义为final类型,可以防止子类修改父类的定义与实现方式,其中private修饰符将其方法隐式的指定为final,自然无法覆盖其父类方法

final类:不允许扩展的类被称为final类。定义final的类不能被继承,且不允许对这个类进行任何改动。如果这个类为final,则这个类中的方法均被隐式的设置为final,但其中的字段可以被设置为final或非final。

语法格式:public final class......

7、多态

一个对象变量可以指示多种实际类型的现象称为多态。多态就是同一个接口,使用不同的实例而执行不同操作。也可以理解为同一个事件发生在不同的对象上会产生不同的结果。

例如:如Student类继承了Person类,若定义Student类的对象为Tom则Tom既是Person类又是Student类。

任何父类出现的地方,我们都可以用子类来替代。

多态存在的三个必要条件:

        1、继承

        2、重写

        3、超类引用子类的对象

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

例1、多态性的体现  Polymorphism.java

package cn.edu.abc.corejava;

public class Polymorphism {
    public static void main(String args[]) {
        get_class(new Student());
        get_class(new Teacher());
    }

    public static void get_class(Person X) 
    {
       X.work();
    }

}

class Person
{
    public void work(){}
}
class Student extends Person
{
    public void eat()
    {
        System.out.println("吃饭");
    }
    public void work()
    {
        System.out.println("Student work :学习");
    }
}
class Teacher extends Person
{
    public void work()
    {
        System.out.println("Teacher work :上课");
    }
}

  

Person类有两个子类:Student,Teacher,均重写了父类的work方法,work()为同一事物,而同一个work方法在Student类下表现为“学习”,而在Teacher类下表现为“上课”,这就体现了同一个事件发生在不同的对象上会产生不同的结果,这就是多态。

8、抽象类

使用abstract关键字定义的类为抽象类,使用这个关键字定义的方法称为抽象方法。抽象类没有具体方法体这个方法本身也没有任何意义,除非它被重写。实际上抽象类除了被继承无任何意义。

只要类中有一个抽象方法,此类就应该被标记为抽象类。

为什么要设置抽象类,一般类不是已经够用了吗?。一般类里定义的方法,子类也可以覆盖,没必要定义成抽象的啊。

        其实不是说抽象类有什么用,一般类确实也能满足应用,但是现实中确实有些父类中的  方法确实没有必要写,因为各个子类中的这个方法肯定会有不同,所以没有必要再父类里写。当然你也可以把抽象类都写成非抽象类,但是这样没有必要。

 其抽象类只能被继承,无法被实例化,即无法创建对应的实例。在抽象类中可以有非抽象方法与抽象方法,但如果有抽象方法该类只能设定为抽象类。

 写成抽象类,这样别人看到你的代码,或你看到别人的代码,你就会注意抽象方法,而知道这个方法是在子类中实现的,所以,有个提示作用。

9、接口

接口是抽象方法的集合。接口中的所有方法都没有方法体,接口只是一种形式,接口自身不能做任何事情。接口修饰符为public,不能使用其他的修饰符,在接口定义的任何字段都是static和final

语法格式:

        public interface Paintable{      //定义接口方法可省略public abstract关键字

                void age();

                }

一个类继承父类的同时再实现一个接口:

语法格式:

        public class parallelogram(子类) extends Quadrangle(超类) implements Paintale {

        .........

        }

1、一个类可以继承多个接口  class 类名 implements 接口1、接口...

2、一个接口可以继承另一个接口 interface intf1 extends intf2

应该注意的是继承接口的子类必须在类中实现接口中的方法接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须宣告为抽象类(Abstract Class)。如下例 

 定义接口中的方法可以省略public abstract关键字

/*解释*/

我们定义一个Age接口,并且定义一个接口方法age()。

(实现接口的类)子类Student、Teacher继承超类Person与接口Age,此时子类中必须实现接口中的方法或将子类其方法设置为抽象类

/*对接口的理解*/

接口类似于招牌,如“做面的流程”(接口A),接口A中定义了“切面”这个方法。一个子类继承了接口A,就必须实现这个接口中的方法,即也要实现“切面”这个方法(可以理解为要想继承“做面的流程”就也必须学会“切面”)。虽然这个子类可以不继承该接口也能实现“切面”方法,如餐厅类也可以自己定义“切面”方法,但显然是不明显的,没有接口那么明确,也增加了代码量。

抽象类和接口的对比

猜你喜欢

转载自blog.csdn.net/m0_61598337/article/details/128273372
今日推荐