Java教程

继承与多态、抽象类与接口

本文主要是介绍继承与多态、抽象类与接口,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

   继承与多态

一、什么是类的继承

1.继承的概念

        Java的继承是指在一个现有类的基础上去构建一个新类,现有类叫父类,而基于现有类构建出的新类叫子类,子类可以拥有父类中的成员。 2.子类的设计 创建类的语法格式如下:
[修饰符] class <类名> {
    各种成员变量的定义;
    各种成员方法的定义;
}

        在Java 中,往往在声明一个类的同时需要继承另一个类,这时就需要使用extends关键字来指明其父类。创建类的完整的语法格式如下:

[修饰符] class <类名> [extends 父类名][implement 接口列表]{
    各种成员变量的定义;
    各种成员方法的定义;
}

3.继承中的protectd

        在上一个模块的学习中,我们知道, 一个类中的成员变量和成员方法的修饰符可以是public、protected、private。 其中,被public修饰的属性可以被子类继承,而被private修饰的则不能被子类继承。那被protected修饰的成员方法和成员变量呢?如果父类和子类在同一个包中,那么protected 等价于public,,如父类和子类不在同一个包中, 那么 protected 等价于private。 4.继承的使用原则         子类可以继承父类中所有可被子类访问的成员变量和成员方法, 但必须遵循以下原则。 (1)子类可以继承父类中被声明为public、protected(父类和子类在同一个包中)的成员变量和成员方法,但是不能继承被private修饰过的成员变量和成员方法。 (2)如果子类声明了一个与父类同名的成员变量, 则子类不能继承父类的成员变量,因为此时,子类中的成员变量隐藏了父类的同名成员变量。 (3)同理,如果子类声明了一个与父类同名的成员方法,则子类不能继承父类的成员方法, 因为此时,子类中的成 员方法隐藏了父类的同名成员方法。 5.super关键字的使用         使用super关键字用来在子类中访问父类中被子类隐藏的成员方法和成员变量。super关键字的用法主要有以下两种: (1)使用super关键字访问父类的构造方法         子类调用父类的构造方法,其具体语法格式如下:
super [参数列表];

(2)使用super关键字访问父类中与子类同名的成员方法和成员变量

        其具体语法格式如下:
super. 成员变量;
super. 成员方法[参数列表];

二、final关键字

1.final修饰变量

        final修饰的变量(包括成员变量和局部变量)会变成常量,只能赋值一次。 2.final修饰类         被 final修饰的类,不能被继承, 即该类不能有子类。 3.final修饰方法         被final修饰的方法,不能被重写,即该类的子类不能重写该方法。 三、什么是多态 1.多态的概念         所谓多态是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使同一个属性或方法在父类及其各个子类中具有不同的含义, 面向对象的多态性提高了程序可复用性、 可扩充性和可维护性。         对面向对象来说, 继承是多态得以实现的基础, 而多态的行为主要包括方法的重载和向上转型。         方法的重载: 指在同一个类中,根据参数列表的不同来区分同名的方法。         向上转型: 指在有继承关系的类中,将子类的引用赋给父类对象,即子类的对象是父类类型。 2.构造方法的重裁          在一个类中,可以定义多个构造方法,这些构造方法的方法名虽然相同,但是它们的参数类型或者参数个数是不同的, 在创建对象时,可以根据参数的类型或个数来选择调用相应的构造方法。 3.成员方法的重裁         在一个类中,可以定义多个同名的成员方法, 虽然方法名相同,但是它们的参数类型或者参数个数是不同的,Java 在执行具有重载关系的方法, 可以根据参数的类型或个数来选择调用相应的成员方法。 4.对象的类型转换         所谓对象的类型转换,就是指向上转型或者向下转型。即 将子类的对象当作父类类型使用, 或者将父类的对象当作子类类型使用,它是多态性的另外一种表现形式。 四、设计工资管理系统 1.任务描述         实现一个名为Person的类和它的子类Employee, 再设计Manager类, 它是Employee 的子类, 最后设计一个类Add()用于涨工资, 普通员工一次能涨 10%, 经理能涨20%. 2.任务目标         (1)学会分析“工资管理系统”子任务实现的逻辑思路。         (2)能够独立完成“工资管理系统”程序的源代码编写、 编译及运行。         (3)实理现解思继路承和多态的相关概念及使用。 3.实现思路         (1)首先设计 Person类, 该类中的属性有: 姓名name String(类型)、 地址address(String类型)、 定义该类的构造方法。         (2)然后设计Employee 类, 该类中的属性有: 工号 ID(String类型)、 工资wage(double类型)、 工龄(int 型)、 定义该类的构造方法。         (3)接着设计 Manger类, 该类中的属性有: 级别 level(String类型)、 定义该类的构造方法。         (4)最后代编码写一个测试类,产生一个员工和一个经理, 给该员工和经理涨工资。 4.实现代码 (1)定义Person类
public class Person {
    private String name="";
    private String address="";
    //定义构造方法
    public Person ( String name, String address) {
    this. name = name;
    this. address = address;
    }
}

(2)定义Employee类并继承Person类。

//继承Person类
public class Employee extends Person{
    private String ID = "";
    private double wage = 0;
    private int age = 0;
    public Employee(String name, String address, String ID, double wage, int age){
        super(name, address);     //调用父类的构造方法
        this. ID = ID;
        this. wage = wage;
        this. age = age;
    }
    public double add (String position){    //判断职位
        if(position = = "0" )
            wage = wage *1.2;
        }
        else{
            wage = wage * 1.1;
        }
        return wage;
    }
    //设置 get/set方法
    public double getWage(){
       return wage;
    public void set Wage (double wage){
        this. wage = wage;
    }
}

(3)定义Manger并继承Employee 类。

public class Manager extends Employee{
    private String level = "";     //1为普通员工,0为经理
    public Manager( String name, String address, String ID, double wage, int age, String level) {
        super( name, address, ID, wage, age);
        this. level = level;
    //设置get/set方法
    public String getLevel (){
        return level;
    public void setLevel ( String level){
        this. level = level;
    }
}

(4)定义测试类Test, 完成相应的操作。

public class Test {
    public static void main( String[] args){
        //新建对象
        Manager normal = new Manager( "wsl", "jit" , " 12" , 1000, 2, "1");
        Manager manager = new Manager(" ctl" , "jitt" , " 123" , 5000, 10, "0");
        //传入职位,Manager类型的对象没有add()方法,所以自动搜寻其父类,调用add()方法
        normal. add( normal. getLevel()) ;
        manager. add (manager. getLevel());
        System. out. println ("TT资:" +normal. get Wage());
        System. out. println ("经理的T资:" +manager. getWage());
    }
}

5.运行结果

 

 

 抽象类与接口

一、什么是抽象类

1.抽象类的定义

        在面向对象的概念中,所有的对象都是通过类来描绘的。但是反过来, 并不是所有的类都是用来描绘对象的, 如果一个类中没有包含足够的信息来描绘一个具体的对象, 这样的类就是抽象类。 简单来说,在Java 中, 如果一个类中包含了抽象方法(只包括方法声明, 而不包含方法体)。则该类就必须定义成抽象类,抽象方法的具体实现则由抽象类派生出的各子类来完成。这使程序的功能描述和功能实现得以分离,此外, 由于一个抽象类可派生多个子类。 因此, 抽象类中的一个抽象方法可以在多个子类中有多种实现方式,这也实现了程序的多态性。

(1)抽象类的定义的语法格式

public abstract class 类名    // 声明抽象类 }
{
        // 声明抽象类成员
}

(2)抽象类成员组成

        a. 成员变量。         b.成员常量。         c.构造方法,有构造方法,但是不能实例化,构造方法用于子类访问父类数据的初始化。         d.成员方法,可以包含限定子类必须完成某些动作的抽象方法(除非子类也是抽象类。否则抽象方法必须在子类中重写), 也可以包含提高代码复用性的非抽象方法。 (3)抽象类的特点         a.抽象类和抽象方法必须使用 abstract关键字修饰。         b.抽象类是不能实例化的,也就是说,不能基于抽象类来创建对象,抽象方法不能有方法体。         c.抽象类的子类要么重写抽象类中所有的抽象方法,要么是抽象类。 2.抽象类的使用         抽象类与抽象方法的使用方法,其中,分别定义抽象类 Animal及两个子类,子类分别覆盖抽象类中的Bark( ) 抽象方法,从而使程序能够用一种方法实现不同动物的叫声。 二、什么是接口 1.接口的定义         如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。 和抽象类的作用类似, 接口也可以把“做什么”和“怎么做”, 即程序的功能和实现分离开来。Java 语言是单一继承语言,即一个类只能直接继承一个父类,这就使 Java的继承结构形成一个树状结构, 这种单一继承关系从某种程度上使Java的继承逻辑变得简单、 清晰。 降低了编程难度,但同时也有了一些局限,可以利用接口弥补这个不足, 即一个子类可以实现多个接口。 (1)抽象类定义的语法结构
[public] interface 接口名 [extend 接口1,接口2......]    //声明接口
{
   //声明接口成员
}
        由于接口中的方法都是抽象的,因此不能通过创建实例化对象的方式来调用接口中的方法, 此时, 还需要一个类通过implements关键字来实现接口中的所有方法,接口的实现类声明格式如下:
[修饰符] class<类名> [extends <父类名>]  [implement接口名]

(2)接口成员组成

        a.成员常量, 接口中只有常量,并且默认为静态。         b.构造方法,,接口中不能有构造方法.         c.成员方法,只能包含限定子类必须完成某些动作的抽象方法。 (3)接口特点         a.接口中只能定义抽象方法,不能定义非抽象方法。         b.类和接口之间不能继承(extends),只能实现(implements)。         c.接口不能实例化,只能对实现接口的子类进行实例化。         d.类可以不重写接口的所有抽象方法,则该类必须定义为抽象类。  2.接口的一对多实现         由于 Java支持接口的多继承, 因此可以在implements后面列出要实现的多个接口, 这些接口名称之间应以逗号分隔, 例如:
[修饰符] class <类名> [extends <父类名>]  [implements <接口1>,<接口2>......]

3.接口的使用

        接口的定义和使用很容易, 但要注意一点,由于系统要求继承接口的类中必须实现接口的全部方法, 因此, 一旦修改了接口内容,很可能会导致相关类变成抽象类,而抽象类是不能实例化的。

三、设计学生管理系统

1.任务描述

        学生管理系统主要用于学生信息的处理和存储,实现学生信息管理的系统化、 科学化、规范化和自动化,其主要功能是对学生各种信息进行日常管理。 如查询、 修改、 增加、 删除等,本案例较为简单地实现了三个类及一个接口,分别是: 学生类、 教师接口、 教师接口实现类、 运行类。训练学生对继承和多态的理解运用,为以后开发功能更加完善的学生管理系统打下良好的基础。

2.任务目标 

        进一步掌握继承和多态的实现方式。

3.实现思路

        本程序设计一个学生类,包括学生姓名、 电话、 年龄等信息。再设计一个教师接口, 规范教师所能做的操作, 最后设计一个子类来实现教师接口, 完成教师对学生信息的录入和查看。 

4.实现代码

(1)定义一个学生类

package studentsystem;
public class Stu{
    //基本属性
    public String name, tel, age;
    public boolean sex;
    public static int i=0;     //人数总和
    private Stu[] s=new Stu[5];     //创建学生表,
    //返回表
    public Stu[] TheStuArrar() { return s;}
    public Stu(){
    }
     //有参构造方法用来向表添加学生
    public Stu( String a, String b, String c, boolean d){
        name=a;
        age=b;
        tel=c;
        sex=d;
    }
//相关属性的get/set方法
    public String getName(){
    return name;
    }
    public void setName(String name) {
        this. name = name;
    }
    public String getTel(){
        return tel;

    }
    public void setTel(String tel){
        this, tel = tel;
    }
    public String getAge() {
        return age;
    }
    public void setAge (String age){
        this. age = age;
    }
    public boolean getSex(){
        return sex;
    }
    public void setSex( boolean sex){
        this. sex = sex;
    }
}  

(2)定义一个教师接口

package studentsystem;
public interface Teacher1{
    //教师拥有对表的操作权限
    abstract public void jiemian (Stu [] st) ;    //初始界面,选择操作
    abstract public void set ( Stu [] st);    //存储
    abstract public void ShowStu(Stu [] st) ;    //查看
}

(3)定义一个具体教师类来实现教师接口

package studentsystem;
import java. util. Scanner;
public class TeacherCan implements Teacher1{
    //界面
    public void jiemian(Stu[] st)     //参数是执行的对象
    }
        System. out. println(" --------学生管理系统-------");
        int a;
        Scanner sc = new Scanner( System. in);
     //一直执行操作,直到某些情况满足就break退出循环 
        for(;;){
            System. out. println (" 1. 查看生信息");
            System. out. println("2. 存储生信息");
            System. out. println("按数字0退出系统");
            a = sc. nextlnt(); 
            if(a= =0) break;
    //用switch判断用户的选择,非法输入无效 
            switch (a){
                case 1:ShowStu(st); break;
                case 2:set(st); break;
                default: System. out. println("输入无效! In");
            }
        }
    }
    //查看
    public void ShowStu(Stu[] st){
        System. out. println("序号"+" \t 姓名:"+" \t年龄:"+ "\t性别:"+" \t电话:");
        //过滤掉空的元素,这里不用成员变量i,所以不担心变量名重复 
        //doo用来展示序号,i遍历st数组
        for( int i=0, doo = 0; i<st. length; i++, doo++){
            if(st[i] = =null) | doo--; continue; }
            System. out. println( (doo+1)+" \t "+st[i]. getName() +" \t "+st[i]. getAge() +" \t" +st[i]. getSex()+" \t "+st[i]. getTel() +" \t ");
         }
    }
    //存储
    public void set(Stu[] st)
    {
        Scanner s= new Scanner( System. in);
        String a,b,c,f;
        boolean d;
        int e;
        //往数组的空元素插入数据
        //条件设置成<=,是为了在内存用完后继续增加时提示空间不足
        for( int it=0; it<= st. length; it++)
        {
             //控制语句,当内存10个用完了时还调用该方法增加人员,提示并退出
            if(Stu. i>=st. length){
                System. out. println("e不足,对象内存(" +st. length+" )已用完! \n");
                break;
            }
            if(st[it] = = null) |
                System. out. println("第"+(Stu. i+1) +"个学生的信息:");
                System. out. print("名:");
                a=s. nextLine();
                System. out. println (":");
                b=s. nextLine();
                System. out. println("电话:");
                c=s. nextLine();
                System. out. println(": (true, false女生)");
                d=s. nextBoolean();
                //往空元素插入新学生
                st[ it] = new Stu(a,b,c,d);
                //人数标记+1 Stu. i++;
                System. out. println("写入成功!按数字0退出,按1继续");
                e=s. nextInt();
                if(e==0) break;
                else s. nextLine();     //这里会产生回车残留,需要用nextLine()吸收
            }
        }
    }
}

(4)定义类Run,完成相应的操作

public class Run{
    public static void main ( String [] args){
        teacherCan t1 = new teacherCan() ;    //new老师
        stu st= new stu() ;     //new学生表
        t1. jiemian(st. TheStuArrar()) ;    //老师进行操作
    }
}

5.运行结果

 

这篇关于继承与多态、抽象类与接口的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!