Java复习:继承、抽象、接口

继承、抽象、接口

第一节:继承

1、定义:
当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可。这时,多个类可以称为子类,单独的这个类称为父类或者超类。在程序中通过extends来实现。
举例说明:学生有年龄、姓名和学习的能力,工人具有年龄、姓名和学习的能力,所以可以把他们两者的共性内容抽取到一个类中。

    class Person
    {
        private String name;
        private int age;
    }
    class Student extends Person
    {
        void study()
        {
            System.out.println("good study");
        }
    }
    class Worker extends Person
    {
        void work()
        {
            System.out.println("good work");
        }
    }

2、特点:
(1)提高了代码的复用性
(2)让类与类之间产生关系,有了这个关系才有了多态的特性
3、注意事项:
(1)千万不要为了获取其他类中的功能,简化代码而继承。必须是类与类之间有所属关系才可以继承。
(2)Java语言中,只支持单继承,不支持多继承。容易发生安全隐患,当功能内容相同时,子类对象不知道执行哪一个。
4、继承的使用:
要使用该体系,就要先查阅父类的描述,因为父类张定义的是该体系中最共性的功能,通过了解共性功能,就可以知道该体系的基本内容。
举例:假若有A、B这两个类

class A                                                class A 
{                                                     {
    void demo1(){}                                       void demo1(){}
    void demo2(){}     假若使用继承来实现代码               void demo2(){} 
}                                                     }
class B                                               class B extendx A
{                                                     {
    void demo1{}                                         void demo3{}
    void demo3{}                                      }
}

右边事例中class B不光拿到了demo1()的功能,还拿到了demo2()的功能,只要观察demo2()的功能是否B应该拥有,若可以就可以使用继承。
5.子父类关系
(1)子父类中的变量关系
①变量之间关系:
简历子类对象,子类和父类的内容都可以应用

class Fu
{
    int num1=4;
}
class Zi extends Fu
{
    int num2=5;
}
class  Demo1
{
    public static void main(String[] args)
    {
        Zi z=new Zi();
        System.out.println(z.num1+"***"+z.num2);
    }
}

结果为这里写图片描述

②this 代表父类中的内容

class Fu
{
    int num=4;
}
class Zi extends Fu
{
    int num=5;
    void show()
    {
        System.out.println(this.num);
    }
}
class  Demo1
{
    public static void main(String[] args)
    {
        Zi z=new Zi();
        z.show();
    }
}

结果:
这里写图片描述
③super代表的是父类对象的引用

class Fu
{
    int num=4;
}
class Zi extends Fu
{
    int num=5;
    void show()
    {
        System.out.println(super.num);
    }
}
class  Demo1
{
    public static void main(String[] args)
    {
        Zi z=new Zi();
        z.show();
    }
}

结果:这里写图片描述

(2)子父类中函数关系
当子类出现与父类一模一样的函数时,子类对象调用该函数会运行子类函数的内容,如同被覆盖一样,其实父类内容在类中依然存在,这种特性为重写或者是覆盖。
注意事项:
①子类覆盖父类必须保证子类权限大于等于父类的权限才可以覆盖(至今学的权限有private public 还有默认权限)
②静态类型只能覆盖静态类型
③重写和重载区别:重载是看同名函数的参数列表。重写或者是覆盖是子父类中的方法要一模一样,包括类型。
举例:

class Tel
{
    void show()
    {
        System.out.println("number");
    }
}
class NewTel 
{
    public void show()
    {
        System.out.println("number");
        //super.show();
        System.out.println("picture");
        System.out.println("name");
    }
}
class Demo1
{
        public static void main(String[] args)
        {       
            NewTel n=new NewTel();
            n.show();
        }
}

结果:
这里写图片描述
(3)子父间的构造函数
在对子类对象进行初始化时,父类的构造函数也会运行。那是因为子类的每一个构造函数默认第一行有一条隐式的语句super();super()会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super()
注意事项:
①因为关键字this.super,都只能在第一行,所以不能存在于同一个构造函数中
②当父类中没有空参数的构造函数时,子类必须手动通过supe语句或者this语句形式来指定要访问的构造函数。当然子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
③父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。
事例说明:

class Fu
{
    Fu()//父类的构造函数
    {
        System.out.println("Fu running");
    }
}
class  Zi extends Fu
{
    Zi()//子类的构造函数
    {
        //super();
        System.out.println("Zi running");
    }
    Zi(int x)
    {
        //super();
        System.out.println("Fu running"+x);
    }
}
class Demo1
{
    public static void main(String[]args)
    {
        //super();
        Zi z=new Zi();
        Zi z1=new Zi(4);

    }
}

结果:
这里写图片描述

6、final关键字
特点:
(1)作为一个修饰符,可以修饰类、函数、和变量。
(2)被final修饰的类不能被继承,为了避免被继承,被子类复写功能。
(3)被final修饰的方法不能被复写
(4)被final修饰的变量是一个常量,之间能赋值一次,即可以修饰成员变量也可以羞死局部变量,当描述事物时,一些数据的出现都是固定的,这时为了增加阅读性,都给这些值起个名字,方便阅读。作为常量,书写格式:所有字母都大写,如果多个单词组成,中间用下划线区分,例:final double MY_PI=3.14;
(5)内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。

第二节:抽象类

1、定义:
当多个类出现相同的功能,但是功能主体不同。这时可以进行向上抽取,这时只需抽取功能定义,而不抽取功能主体。
2、特点:
(1)抽象方法一定定义在抽象类中
(2)抽象类和抽象方法必须用abstract关键字来修饰。
(3)抽象类不可以被实例化,也就是不可以用new创建对象。抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。
(4)抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,如果子类只是覆盖了部分抽象方法,那么该子类还是个抽象类。
事例说明:

abstract class Student
{
    abstract void study();//强制子类具有一些功能,需要将父类中的复写掉才能建立对象
    //abstract void study1();//若将上此句就会产生错误,相当于这句话放到了子类中,抽象方法一定在抽象类中,则BaseStudent和AdvStudent类也抽象化了   
}
//基础班学生类
class BaseStudent extends Student
{
    void study()
    {
        System.out.println("Base Study");
    }
}
//高级班学生类
class AdvStudent extends Student
{
    void study()
    {
        System.out.println("Adv Study");
    }
}
class Demo
{
    public static void main(String[] args)
    {
        new BaseStudent().study();
        new AdvStudent().study();
    }
}

结果:
这里写图片描述

3、总结:
(1)抽象类和一般类没有太大的不同。该如何描述事物,还是如何描述事物。只不过,该事物中出现了一些不知道具体内容的方法部分。这些不确定的部分,也是该事物的功能,需要明确出来,但是无法定义主体。通过抽象方法来表示。
(2)抽象类比一般类多了个抽象函数。就是在类中可以定义抽象方法。
(3)抽象类不可以实例化,但是也有构造函数。供子类实例化调用。
事例卓明:

/**
需求:
假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性: 
姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个 
奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方 
法进行属性访问。 
员工类:name id pay 
经理类:继承了员工,并有自己特有的bonus。 
*/  
abstract class Employee   //共有的属性和功能
{
    private String name;//姓名
    private String id;//id
    private double pay;//工资
    Employee(String name,String id,double pay)//构造函数
    {
        this.name=name;
        this.id=id;
        this.pay=pay;
    }
    public abstract void work();//抽象函数,定义功能
}
class Manger extends Employee
{
    private int bonus;//奖金
    Manger(String name,String id,double pay,int bnus)
    {
        super(name,id,pay);//name id pay应经私有化,不能从其他类中调用,只能调用构造函数
        this.bonus=bonus;
    }
    public void work()
    {
        System.out.println("Manger work");
    }
}
class Pro extends Employee
{
    Pro(String name,String id,double pay)
    {
        super(name,id,pay);
    }
        public void work()
    {
        System.out.println("Pro work");
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Pro p=new Pro("E_LI_A_E","20150329",20000);
        p.work();
        new Manger("YI_LI_O_E","20140329",19999,10000).work();
    }
}

结果:
这里写图片描述
4.模板方法设计模式:

/**
需求:获取一段代码的运行时间
原理:获取程序开始时间和结束时间,并相减
思路:在定义功能时候。功能的一部分是确定的,但是有一部分是不确定的,而不确定的部分在使用不确定的部分,那这时就将不确定的部分暴露出来,有该类的子类完成
*/
abstract class  GetTime  
{  
    public final void getTime()
    {  
        long start=System.currentTimeMillis();//开始执行时间  
        runcode();
        long end=System.currentTimeMillis();//执行结束时间  
        System.out.println("毫秒"+(end-start));  
    }  
    abstract void runcode();//将不确定的事物抽象出去  
}  


class SubTime extends GetTime  //运行的程序  
{  
    void runcode()  
    {  
        for(int x=0;x<1000;x++)  
            System.out.print(x);  
    }  
}  
class Demo
{  
    public static void main(String[] args)   
    {  
        new SubTime().getTime();   
    }  
}  

结果:
这里写图片描述

第三节:接口

1、定义:
接口,可以被认为是一个特殊的抽象类。当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。class用来定义类,interface来定义接口,子类中用implements实现。
2、格式:
(1)接口中常见定义:常量,抽象方法。
(2)接口中的成员都有固定修饰符。
常量:public static final int NUM=3;
方法:public abstract void show();
3、特点:
(1)implements(实现)类与类之间的 继承是因为从类中有非对象内容可以直接用接口里面全抽象,子类一继承,则全部拿去复写。
(2)implements需要被子类对接口的抽象方法全部覆盖掉,子类才可以实例化,否则为一个抽象类
事例说明:

interface Inter
{
    public static final int NUM=3;
    public abstract void show();
}
class Test implements Inter
{
    public void show(){}//要将子类中的show()方法覆盖掉
}
class Demo
{
    public static void main(String[] args)
    {
        Test t=new Test();
        System.out.println(t.NUM);
        System.out.println(Test.NUM);
        System.out.println(Inter.NUM);
    }
}

结果:
这里写图片描述

(3)接口可以被类多实现,也是对多继承不支持的转换形式。
事例说明:

interface Inter
{
    public static final int NUM=3;
    public abstract void show();
}
interface InterA
{
    public abstract void show();
}
class Test implements Inter,InterA  //多继承
{
    public void show(){}
}

(4)一个类在继承一个类的情况下还可以多实现

事例说明:

interface Inter
{
    public static final int NUM=3;
    public abstract void show();
}
interface InterA
{
    public abstract void show();
}
class demo
{
    public void function(){}
}
class Test extends demo implements Inter,InterA
{
    public void show(){}
}

(5)接口之间的关系
事例说明:

interface A                                         interface A 
{methodA(){}}                                       {methodA(){}}
interface B extends A        也可以这样写             interface B
{methodB(){}}                                       {methodB(){}}
interface C extends B                               interface C extends B,A
{mathodC(){}}                                       {mathodC(){}

4、接口的事例
事例说明:

 abstract class Student  //共性的内容,学生都要学习、睡觉,而学习的内容不一样所以定义为抽象的
{     
    abstract void study();  
    void sleep()  
    {  
        System.out.println("sleep");  
    }  
} 
interface Smoking  
{  
    void smoke();  
} 
interface Drinking
{
    void drink();
}
 //学生张三扩展了抽烟的功能
class Zhangsan extends Student implements Smoking  
{  

    void study()  
    {  
        System.out.println("Zhangsan_study");  
    }  
    public void smoke()  
    {  
        System.out.println("Zhangsan_smoking");  
    }  
}  
  //学生李四扩展了喝酒功能
class Lisi extends Student   implements Drinking
{      
    void study()  
    {  
        System.out.println("Lisi_study");  
    }  
     public void drink()  
    {  
        System.out.println("LIsi_drinking");  
    }  
}  

class Demo
{  
    public static void main(String[] args)   
    {  
        Zhangsan z = new Zhangsan();  
        z.study();  
        z.smoke();  
        new Lisi().study();  
        new Lisi().drink();  
    }  
}  

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值