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

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)

 

 

 

    

posted @ 2016-08-05 09:45  GumpYan  阅读(1965)  评论(0编辑  收藏  举报