Java基础10-接口,抽象类以及异常

原创 2012年04月05日 22:20:20

一.接口
 1.什么是接口
  接口是特殊的抽象类,其内部方法都是抽象的
 
 2.接口与抽象类的区别:
  a.接口是interface;抽象类是abstract class
  b.接口的方法都是抽象的;抽象类的方法可以不是抽象的
  c.接口的成员有默认修饰符:方法是public abstract,变量是public static final;抽象类没有默认修饰符
  d.接口的实现使用implements关键字;抽象类的继承使用extends关键字
  e.接口可以被多实现;抽象类只能被单继承
  
 
3.什么时候使用抽象类和接口?
  a.当存在继承关系时使用抽象类;没有继承关系时就使用接口
  b.当方法都是抽象时使用接口;若既有抽象方法,又有实例方法时,使用抽象类
  
 
注:
  接口与接口,使用extends关键字;
  实现接口后,子类方法必须为public;
  
 
4.面试题一:
  一个类可以实现两个接口吗?任意两个接口都可以吗?
  
  答: 可以.不可以.
   因为若是两个接口的方法名相同,参数列表相同,但其返回值类型不同,此时子类就不能同时实现这两个接口了.
   如:
    interface A {
     int fun();
    }
    interface B {
     void fun();
    }
 
 5.面试题二:
  什么情况下,会将子类类型强转为父类类型呢?
  
  答:当一个子类对象能够匹配多个重载方法而且方法的形参都是该子类实现的父类类型们.
  这时会出现调用不明确的情况,所以需要进行强转为父类类型.
  如:
   interface Teacher {
    void teach();
   }
   interface Coder {
    void code();
   }
   
   class Person implements Teacher,Coder {
    public static void main(String[] args) {
     Person p = new Person();
     p.work( (Teacher)p );  //强转类型转换
     p.work( (Coder)p );    //强转类型转换
    }
    
    @Override
    public void teach(){ }
    
    @Override
    public void code(){ }
    
    public static void work(Teacher t) {
     t.teach();
    }
    
    public static void work(Coder c) {
     c.code();
    }
   }
   
二.策略设计模式-StrategyPattern
 使用接口,降低耦合性
 
 如:
  class TestDemo {
   public static void main(String[] args) {
    int[] arr={1,4,6,7,3,5,9,-6,-34,67,-12};
    Printer.print(arr);
    
    //需求: 要打印其中的正数 (此时就可以使用策略设计,添加过滤器,使用接口来实现)
    
    Printer.print(arr, new Filter(){  //add: 使用匿名内部类
     @Override
     public boolean accept() {
      return i >= 0;
     }  
    });
    
   } 
  }
  
  class Printer {
   public static void print(int[] arr) {
    for(int i=0;i<arr.length;i++)
     System.out.print(arr[i]+" ");
    System.out.println();
   }
   
   public static void print(int[] arr,Filter f) {       //add
    for(int i=0;i<arr.length;i++)
     if(f.accept(arr[i]))                         //add
      System.out.print(arr[i]+" ");
    System.out.println();
   }
  }
  
  interface Filter {
   boolean accept(int i);
  }
  
  
三.内部类: ( 内部类可以访问外部类成员 )
 
类中:
  成员内部类
  静态内部类
 
方法中: 
  局部内部类
  匿名内部类
 
 
1.什么是内部类
  在内部类中定义的类,就是内部类
  
 2.成员内部类: ( A$B.class )
 
 a.什么是成员内部类
   定义在类的成员位置的内部类,就是成员内部类
   创建该内部类的对象,必须先创建外部类对象,才能通过外部类对象创建内部类对象;
  注:
   创建格式为: 外部类名.内部类名 变量名= new 外部类名().new 内部类名();
   一个外部类可以创建多个内部类对象,但一个内部类对象只能对应一个外部类对象;
   
  b.什么时候使用成员内部类?
   当一个类想要访问另一个类的成员时
  
  
c.内部类访问外部类的成员的方式:
   使用: 外部类名.this.成员名 


  注:
   在方法中,"this" 代表当前方法的对象,而"外部类.this" 代表当前方法的对象的外部类对象
   外部类不能访问内部类成员
   
  
d.内部类中不能定义静态成员
   因为内部类必须依赖外部类对象才能创建对象,而static是指不需创建对象就可以使用
   
 
3.局部内部类: ( A$1B.class )
 
 a.什么是局部内部类
   定义在方法中的内部类,就是局部内部类
   
  b.局部内部类与成员内部类的区别:
   局部内部类,只能在方法中使用;成员内部类可以在外面使用
   创建局部内部类的代码在方法中,而且必须写在类定义的后面;
      
  
c.方法中的内部类怎么创建对象
   在方法中直接使用 new 类名()即可
   
  d.方法中的内部类怎么访问方法中的局部变量
   局部内部类访问方法的局部变量时,该局部变量必须使用final修饰;  
   
  如:
   class TestDemo {
    public static void main(String[] args) {
     new A().fun();
    } 
   }
   
   class A {
   
    class B {
     B() {
      System.out.println("成员内部类B..");
     }
    }
    
    void fun() {
    
     class B {
      B() {
       System.out.println("局部内部类B..");
      }
     }
     
     /*
     B b = new B(); 
//1.这边创建B对象是根据从内到外的优先级进行选择的,只有当内部不存在就会向外寻找
     */
     
     //需求: 当前代码下,
     //创建成员内部类B的对象:
A.B b2 = new A.B();
     //创建外类B的对象的方法:
包名.B b3 = new 包名.B();
     
    }
   }
   
   class B {
    B() {
     System.out.println("外部类B..");
    }
   }
   
   
 
4.匿名内部类 ( A$1.class )
 格式:
  new 父类名(){
   //重写方法
  }


  a.什么是匿名内部类
   没有名字的局部内部类,就是匿名内部类
  
  b.什么时候使用匿名内部类
   局部内部类只需使用一次,使用匿名内部类可以简化书写
 
  c.匿名内部类的class文件名
   A$1.class
   
 5.静态内部类
  a.什么是静态内部类
   使用static修饰的内部类
   
  b.静态内部类和普通的类中内部类的区别
   创建对象: 静态内部类不需创建外部类对象,就可以直接建立内部内部类 ( 外部类名.内部类名 变量名 = new 外部类名.内部类名(); )
       成员内部类需要通过创建外部类对象来创建自己的对象 ( 外部类名.内部类名 变量名 = new 外部类名().new 内部类名(); )
   访问外部成员: 静态内部类只能访问外部类的静态成员,而不能访问非静态成员
   定义静态成员: 静态内部类可以定义静态成员;而成员内部类是不可以定义静态成员( 静态变量/方法/代码块 ),可以定义静态常量
   


三.异常
 
 Throwable
 --Error
    --
 --Exception
    --RuntimeException
    --
  
 1.什么是异常
  异常就是程序运行过程中出现的一些错误, 使用throw关键字抛出的一些对象.
  可以通知调用处, 调用处下面的代码不会再执行了.
  
 2.异常的处理方式
 
 a.声明
   若是没有处理,则需要在方法上(参数列表后面)使用"throws 异常名"进行声明,将异常继续向上抛出
  
  b.捕捉
   try {
   
   }catch(异常名 变量名) {
    //处理代码
   }
  
 3.异常的分类
 
 a.编译时异常
   Exception中除了RuntimeException的部分, 编译之前在代码中必须对其进行声明或捕捉, 否则编译报错
   
  b.运行时异常
   RuntimeException或其子类, 在代码中可以不对其进行处理, 编译不报错.
   这类异常经常会出现, 例如数组索引越界, 空指针, 算数异常, 如果对其进行处理, 非常麻烦, 代码可读性也会下降.
   
 4.多个异常的处理方式
  a.声明
   在方法上使用"throws 异常1名,异常2名"进行声明
  
 
 b.捕捉
   try {
   
   }catch(异常1名 变量名) {
    //处理代码
   }catch(异常2名 变量名) {
    //处理代码
   }


  注:
   异常捕捉的书写顺序: 子类异常放在前面
  
 5.子类重写父类方法时注意的异常问题
  重写的条件之一: 子类的方法只能抛出父类方法异常的子集,不能抛出比父类更多的异常
 如:
  class A {
   void fun() throws Exception {
   
   }
  }
  
  class B {
   @Override
   public void fun() throws FileNotFoundException { //可以不抛,也可以抛出相同的异常,也可以抛出父类异常的子类!!!!
   
   }
  }
  
 6.finally的使用
  finally是配合try使用的, 只要执行了try中的代码, finally中的代码就一定会执行. (一些特殊情况除外:如System.exit(0); )
 
 注:
  class TestDemo {
   public static void main(String[] args) throws Exception {   
    /*
    打印结果一:(System.out,println(10/1);)
     10
     异常处理之前
     finally语句
     
    打印结果二:(System.out,println(10/0);)
     异常处理
     finally语句
    */
    try {
     System.out.println(10/1);           //
     System.out.println("异常处理之前");
     return ;
    }catch(Exception e) {
     System.out.println("异常处理..");
    
    }finally {    
     System.out.println("finally语句");
    }
   } 
  }
  
  
补充:
 猴子分桃问题
 注:
  class TestDemo {
   public static void main(String[] args) {   
    
    outer:
     for(int i=0;i<9999;i++) {
      int count=i; 
      for(int j=0;j<5;j++){
       if( (count-1)%5==0 )
        count = (count-1)/5*4;
       else
        continue outer;
      }  
      System.out.println(i);       
     }
    
   } 
   
  }

JavaSE之异常

-
  • 1970年01月01日 08:00

java里抽象类用法

一、定义 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract ...
  • applepie1
  • applepie1
  • 2012-02-16 09:42:46
  • 6588

为什么静态成员、静态方法中不能用this和super关键字

为什么静态成员、静态方法中不能用this和super关键字 1.     在静态方法中是不能使用this预定义对象引用的,即使其后边所操作的也是静态成员也不行. 因为this代表的是调用这...
  • u010479322
  • u010479322
  • 2016-06-21 21:25:22
  • 6259

Java学习笔记

(代理和适配器) 1.java中不能重载运算符 2.java 接口为了规范类的行为,抽象类则是不同行为可以用抽象方法表示 3.java中的常数定义  private final static i...
  • MrGeroge
  • MrGeroge
  • 2016-09-28 21:32:05
  • 198

JavaScript实现抽象类

抽象类和虚函数    虚函数是类成员中的概念,是只做了一个声明而未实现的方法,具有虚函数的类就称之为抽象类,这些虚函数在派生类中才被实现。抽象类是不能实例化的,因为其中的虚函数并不是一个完整的函数,不...
  • superying
  • superying
  • 2010-01-08 11:01:00
  • 891

Java 抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 抽象类除了不能实例化对象...
  • XiaoXiaoPengBo
  • XiaoXiaoPengBo
  • 2016-03-02 09:12:57
  • 234

JavaSE学习(6) 面向对象类和对象(5)抽象类、接口、final

抽象类、接口、final 抽象类: 父类方法的不确定性时,可以用abstract关键字来修饰该方法(抽象方法),用abstract来修饰该类(抽象类) 1、用abstract关键字来修饰一个类时,这个...
  • u010977250
  • u010977250
  • 2016-12-07 21:33:20
  • 108

java普通类、抽象类和接口的再学习

声明:    感谢能有以下参考学习链接的分享使我个人在初期学习时得以拓展, 正文内容仅为以下链接文章的个人摘录+总结,请大家以原链接经典内容为主加以学习, 如有侵犯敬请告知,谢谢!!! http://...
  • xastdm
  • xastdm
  • 2016-08-05 15:03:26
  • 392

C++之继承类中的this指针

#include #include using namespace std;class A { public: A() { cout
  • maoliran
  • maoliran
  • 2016-06-14 19:49:14
  • 95

JavaScript 类、对象、this指针浅析

刚刚接触JavaScript不久,一开始认为它不过是个简单的脚本语言而已,但是在平常或多或少的接触中,对于this指针、全局和局部变量等理解的都不深刻,所以找了些资料看看。 一、类 和实例(对象) ...
  • applepie1
  • applepie1
  • 2011-12-24 12:02:32
  • 1590
收藏助手
不良信息举报
您举报文章:Java基础10-接口,抽象类以及异常
举报原因:
原因补充:

(最多只允许输入30个字)