• 接口&抽象类&继承&父类和子类


    1.接口是什么?

      接口可以理解为一个特殊的抽象类,是由全局常量和公共抽象方法组成的。

      所以,如果,一个抽象类的方法都是抽象的,那么就可以通过接口的形式来表示。

      class 用于定义类

      interface 用于定义接口

    2.接口中成员定义的格式:

      常量  public static final

      抽象方法  public abstract(这里的抽象方法必须有public修饰

    3.接口是不可以创建对象的,因为有抽象方法,必须被子类实现子类对接口中的方法全部覆盖后,子类才可以实例化。(抽象类是不可以实例化的

    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(){};
    }
    //可以看到这个Test类既继承了Demo类,又实现了Inter,InterA接口,所以既具备了Demo的功能,又具备了接口的功能,这样就扩展了Test的功能
    class InterfaceDemp{
    	public static void main(String[] args){
    		Test t=new Test();
    		System.out.println(t.NUM);
    	}
    }
    

    5.关于抽象类

    栗子1:

    abstract class Student{
    	abstract void study();
    	abstract void study1();
    }
    class BaseStudent extends Student{
    	void study(){
    		System.out.println("base study");
    	}
    	void study1(){
    		System.out.println("base study1");
    	}
    }
    //可以看到子类必须覆盖抽象类中所有的方法,如果子类只覆盖了部分抽象方法,则该子类还是个抽象类。
    

      注意:(1)抽象类中可以不存在任何成员可以有非抽象方法

         (2)抽象类可以被抽象类继承,结果还是抽象类。

         (3)抽象类只能作为其他类的基类,不能直接被实例化。

         (4)如果一个非抽象类从抽象类这派生,则其必须通过覆盖来实现所有继承而来的抽象成员。

    栗子2:

    abstract class Person{
    	public abstract void sayHello();
    	public void about(){
    		System.out.println("sayHello");
    	}
    }
    class Nurse extends Person{//建立实体类Nurse继承Person
    	//没有覆盖抽象方法sayHello,这个类是错误的。
    }
    abstract class Worker extends Person{//建立抽象类Worker继承Person
    	//抽象类继承抽象类,可以不覆盖抽象方法sayHello,这个类是正确的。
    }
    

    也就是说,子类继承父抽象类的时候,必须继承父类里面的抽象方法。哪怕用空的表示也是可以的

    如:父类中有abstract public void myfunc();

      子类中,就可以这样,public void myfunc(){};  

    栗子3:

    关于抽象类与最终类(final修饰的类),下列说法错误的是?D错误

      A.抽象类能被继承,最终类只能被实例化。

      B.抽象类和最终类都可以被声明使用

      C.抽象类中可以没有抽象方法,最终类中可以没有最终方法

      D.抽象类和最终类被继承时,方法可以被子类覆盖

    解释:抽象类时专门拿来被继承的,其实也可以没有抽象方法。抽象类是不能实例化的,实例化必将加载类,然后根本不知道抽象方法的方法体大小,所以不能实例化。

    final类之所以被定义为final类是认为这个类已经很完美了,不希望被继承被扩展或者被修改。不可以被覆盖。
     
    栗子4:

      方法的重写(override)两同两小一大原则:

      A.方法名相同,参数类型相同

      B.子类返回类型小于等于父类方法返回类型,

      C.子类抛出异常小于等于父类方法抛出异常,

      D.子类访问权限大于等于父类方法访问权限。

      已知如下类定义:

    class Base {  
     public Base (){ 
     //... 
     }  
     public Base ( int m ){ 
     //... 
     }  
     public void fun( int n ){ 
     //... 
     } 
    }  
    public class Child extends Base{  
     // member methods  
    }  
    

      如下哪句可以正确地加入子类中?  D

       A.private void fun( int n ){ //...}

       B.void fun ( int n ){ //... }
       C.protected void fun ( int n ) { //... }

       D.public void fun ( int n ) { //... }

    子类方法的权限至少要大于父类方法的权限,只能选D

    栗子5:

    下面代码运行结果是(A)

    public class Test{ 
        public int add(int a,int b){   
             try {
                 return a+b;      
             } 
            catch (Exception e) {  
                System.out.println("catch语句块");
             }
             finally{ 
                 System.out.println("finally语句块");
             }
             return 0;
        } 
         public static void main(String argv[]){ 
             Test test =new Test(); 
             System.out.println("和是:"+test.add(9, 34)); 
         }
    } 

      A.finally语句块

       和是:43

      B.和是:43

       finally语句块

    解释:1.finally{}代码块比return先执行
       2.多个return是按顺序执行的的,多个return执行了一个后后面的return就不会执行了。
       3. 记住一点,不管有不有异常抛出, finally都会在return返回前执行

    6.继承

      (1)在Java中,只支持单继承一个类只能有一个父类

      (2)字符类出现后,类中成员的特点也有所改变

        1)变量:

         --- 如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this(this代表本类对象的引用

         --- 如果子类要访问父类的同名变量,用super (代表父类对象的引用

    class Fu{
    	int num=4;
    }
    class Zi extends Fu{
    	int num=5;
    	void show(){
    		System.out.println(super.num);//访问父类中的同名变量,用super
    		System.out.println(this.num);//访问本类中的变量,用this
    	}
    }
    class ExtendsDemo{
    	public static void main(String[] args){
    		Zi z=new Zi();//new一产生,就会先加载父类的class Fu,然后再加载子类class Zi
    		z.show();
    	}
    }

        2)子父类函数的特点——覆盖(重写)

          --- 子类覆盖父类必须保证子类权限大于父类权限,如父类中定义void show(){},而子类中确实private void show(){},这样子类就不能覆盖父类

          --- 静态只能覆盖静态

        3)字符类中的构造函数

          在子类对象进行初始化时,父类的构造函数也会运行,那是因为子类中所有的构造函数默认第一行有一条隐式语句super();

          这个super()回访问父类中空的构造函数super.属性,可以访问父类的属性。

    class Fu{
    	Fu(int x){//父类的构造函数
    		System.out.println("Fu:"+x);
    	}
    }
    class Zi extends Fu{
    	Zi(){//子类构造函数
    		super(4);//这个要手动自己去定义,访问指定的父类构造函数
    	}
    	Zi(int x){
    		this();//这个就是访问自己本类中的构造函数了,Zi(){}
    	}
    }
    

      总结继承会破坏封装性,因为会将父类的实现细节暴露给子类

     栗子:

      对文件名为Test.java的java代码描述正确的是(C)

    class Person {
        String name = "No name";
        public Person(String nm) {
            name = nm;
        }
    }
    class Employee extends Person {
        String empID = "0000";
        public Employee(String id) {
            empID = id;
        }
    }
    public class Test {
        public static void main(String args[]) {
            Employee e = new Employee("123");
            System.out.println(e.empID);
        }
    }
    

      A.输出:0000

      B.输出:123

      C.编译报错

      D.输出:No name

    解释:

      子类在实例化过程中,一定要访问父类中的构造函数。而且默认都会访问父类中空参数的构造函数。如果父类中没有空参数的构造函数时,子类必须手动通过super语句形式访问父类中的构造函数

      所以题目中,子类Employee中没有super(nm);所以编译会有错误。

    如:

    class Person{
            private String name;
            private int age;
            public Person(String name,int age){
                 this.setName(name);
                 this.setAge(age);
    }  
    }    
    class Student extends Person{
            private String school;
            public Student(String name,int age,String school){
                       super(name,age);
                       this.setSchool(school);
    }
    }        
    

      可以看到子类Student中,有super(name,age)

        

  • 相关阅读:
    查看Ubuntu操作系统位数 Anny
    no such file to load zlib when using gem install Anny
    Error: shasum check failed for /tmp/npm1316662414557/13166624159930.13772299513220787/tmp.tgz Anny
    Future接口的应用
    ScheduledThreadPool
    弄了个群
    阻塞与中断
    获得CPU个数
    文件路径问题
    一个日志服务器的框架
  • 原文地址:https://www.cnblogs.com/GumpYan/p/5740048.html
Copyright © 2020-2023  润新知