Java学习笔记

接口 & 多态 & 类型强制转换 & 内

2017-02-08  本文已影响151人  奋斗的老王

一个类最多只能有一个直接的父类, 但是有多个间接的父类, java是单继承

接口概述

interface 接口名{
    
}

实现接口的格式:

    class  类名 implements 接口名{
    
    }
interface A{

    //成员变量
    public static final int i=10;
    //成员函数
    public void print();
}


class Demo  implements A{ // Demo就实现了A接口
    public static void main(String[] args) 
    {
        Demo7 d = new Demo7();
        d.print();
    }
    //实现接口中的方法
    public void print(){
        System.out.println("这个是接口中的print方法...");
    }
}

接口的作用:

  1. 程序的解耦 ( 低耦合 )
  2. 定义约束规范
  3. 拓展功能
//普通的铅笔类
class Pencil{
    
    String name;
    public Pencil(String name){
        this.name = name;
    }

    public void write(){
        System.out.println(name+"沙沙的写...");
    }
}

//橡皮接口
interface Eraser{
    public void remove();
}

//带橡皮的铅笔
class PencilWithEraser extends Pencil implements Eraser {

    public PencilWithEraser(String name){
        super(name);
    }
    public void remove(){
        System.out.println("涂改,涂改....");
    }
}

class Demo{
    public static void main(String[] args) {
        //System.out.println("Hello World!");
    
        PencilWithEraser p = new PencilWithEraser("2B铅笔");
        p.write();
        p.remove();
    }
}

类与接口之间关系 : 实现关系

            class A{
                
                public void print(){
                    System.out.println("AAAAAA");
                }
            }

            class B{

                public void print(){
                    System.out.println("BBBBBB");
                }
            }


            class C extends A ,B{
            
            }
            
            new C().print();

多态

类型强制转换

//动物类
abstract class Animal{
    String name;
    public Animal(String name){
        this.name = name;
    }
    public abstract void run();
}

//老鼠
class  Mouse extends Animal{
    public Mouse(String name){
        super(name);
    }
    
    public  void run(){
        System.out.println(name+"四条腿慢慢的走!");
    }

    //老鼠特有方法---打洞
    public void dig(){
        System.out.println("老鼠在打洞..");
    }
}

//鱼
class Fish extends Animal{
    public Fish(String name){
        super(name);
    }

    public  void run(){
        System.out.println(name+"摇摇尾巴游啊游 !");
    }
    //吹泡泡
    public void bubble(){
        System.out.println(name+"吹泡泡...!");
    }
}

class Demo
{
    public static void main(String[] args) 
    {
        /*
        Animal a = new Mouse("老鼠");  //多态
        //调用子类特有的方法
        Mouse m  = (Mouse)a;  //强制类型转换
        m.dig();
        */

        Mouse m = new Mouse("米老鼠");
        Fish f = new Fish("草鱼");
        print(f);
    }

    //需求: 定义一个函数可以接收任意类型的动物对象,在函数内部要调用到动物特有的方法
    public static void print(Animal a){ // Animal a   = new Mouse("米老鼠");
        if(a instanceof Fish){
            Fish f = (Fish)a;
            f.bubble();
        }else if(a instanceof Mouse){
            Mouse m = (Mouse)a;
            m.dig();
        }
    }
}

多态下的类型强制转换

interface Dao{  //接口的方法全部都是非静态的方法。
    public void add();
    public void delete();
}

//接口的实现类
class UserDao implements Dao{
    
    public void add(){
        System.out.println("添加员工成功!!");
    }
    public void delete(){
        System.out.println("删除员工成功!!");
    }
}

class Demo
{
    public static void main(String[] args) 
    {
        //实现关系下的多态
        Dao d = new UserDao(); //接口的引用类型变量指向了接口实现类的对象。
        d.add();
    }
}

内部类

//外部类
class Outer{
    
    //成员变量
    int x = 100; // Outer.class文件被加载到内存的时候存在内存中。  静态的成员数据是不需要对象存在才能访问。

    //成员内部类
    static  class  Inner{      

        static  int i = 10;
        public void print(){
            System.out.println("这个是成员内部类的print方法!"+i);
        }
    }

    //在外部的方法中创建了内部类的对象,然后调用内部 方法。
    public void instance(){
        Inner inner = new Inner();
        inner.print();
    }
}

//其他类
class Demo{
    public static void main(String[] args) {
        /*
        System.out.println(Outer.Inner.i);
        
        Outer outer = new Outer();
        outer.instance();
        
        Outer.Inner inner = new Outer().new Inner();
        inner.print();
        */

        Outer.Inner inner = new Outer.Inner();
        inner.print();
    }
}

局部内部类

class  Outer{

    String name= "外部类的name";
    public void test(){
        //局部变量
        final   int y =100;  // y 什么时候从内存中消失? 方法执行完毕之后y消失。

        //局部内部类
        class Inner{     /*
        当test方法执行完毕之后,那么y马上从内存中消失,而Inner对象在方法执行完毕的时候还没有从内存中消失,而inner对象的print方法还在访问着y变量,这时候的y变量已经消失了,那么就给人感觉y的生命变量已经被延长了

        解决方案: 如果一个局部内部类访问一个局部变量的时候,那么就让该局部内部类访问这个局部变量的复制品               
                      */
            int x = 10;

            public void print(){
                System.out.println("这个是局部内部类的print方法.."+y);
            }   
        }
        
        Inner inner = new Inner();  //这个inner对象什么时候消失?  Inner对象的生命周期比局部变量y的生命周期要长。
        inner.print();
    }
}

class Demo{
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.test();
    }
}

内部匿名类

abstract class Animal{
    public abstract Animal run();
    public abstract void sleep();
}

class Outer{
    public void print(){
        //需求: 在方法内部定义一个类继承Animal类,然后调用run方法与sleep()。
        
        /*
        //局部内部类
        class Dog extends Animal{
            
            public void run(){
                System.out.println("狗在跑..");
            }
            public void sleep(){
                System.out.println("狗趴在睁开眼睛睡..");
            }
        }
        
        //创建对象
        Dog d = new Dog();
        d.run();    
        d.sleep();
        */  
        //匿名内部类 :匿名内部类只是没有类名,其他的一概成员都是具备的。
        // 匿名内部类与Animal是继承 的关系。  目前是创建Animal子类的对象. 
    Animal  a = new Animal(){  //多态
        
            //匿名内部的成员 
            public Animal run(){
                System.out.println("狗在跑..");
                return this;
            }
            
            public void sleep(){
                System.out.println("狗趴在睁开眼睛睡..");
            }

            //特有的方法
            public void bite(){
                System.out.println("狗在咬人..");
            }
        };
    
        a.bite();
        a.run();
        a.sleep();
    }
}

class Demo
{
    public static void main(String[] args) 
    {
        //System.out.println("Hello World!");
        
        Outer outer = new Outer();
        outer.print();
    }
}

异常

class Demo
{
    public static void main(String[] args) 
    {
        /*
        //创建了一个Throwable对象。
        Throwable t = new Throwable("头晕,感冒..");
        String info = t.toString();
        String message = t.getMessage();
        System.out.println("toString: "+ info);  // java.lang.Throwable  包名+类名 = 完整类名
        System.out.println("message: "+ message);
        */
        test();
    }

    public static void test(){
        //
        Throwable t = new Throwable();
        t.printStackTrace();
    }
}
class Demo
{
    public static void main(String[] args) 
    {
        //java虚拟机在默认的情况下只能管理64m内存。
        byte[] buf = new byte[1024*1024];
        System.out.println("Hello World!");
    }
}

异常处理

捕获处理的格式:
            try{
                可能发生异常的代码;
            }catch(捕获的异常类型 变量名){
                处理异常的代码....
            }
  - 捕获处理要注意的细节:
        1. 如果try块中代码出了异常经过了处理之后,那么try-catch块外面的代码可以正常执行
        2. 如果try块中出了异常的代码,那么在try块中出现异常代码后面的代码是不会执行了
        3. 一个try块后面是可以跟有多个catch块的,也就是一个try块可以捕获多种异常的类型
        4. 一个try块可以捕获多种异常的类型,但是捕获的异常类型必须从小到大进行捕获,否则编译报错

- 方式二:抛出处理(throw throws)
  - 抛出处理要注意的细节:
        1. 如果一个方法的内部抛出了一个异常对象, 那么必须要在方法上声明抛出
        2. 如果调用了一个声明抛出异常 的方法, 那么调用者必须要处理异常
        3. 如果一个方法内部抛出了一个异常对象, 那么throw语句后面的代码都不会再执行了(一个方法遇到了throw关键字, 该方法也会马上停止执行的)
        4. 在一种情况下, 只能抛出一种类型异常对象

  - throw 与 throws 两个关键字:
        1. throw关键字是用于方法内部的,throws是用于方法声声明上的
        2. throw关键字是用于方法内部抛出一个异常对象的,throws关键字是用于在方法声明上声明抛出异常类型的
        3. throw关键字后面只能有一个异常对象,throws后面一次可以声明抛出多种类型的异常
class Demo
{
    public static void main(String[] args) 
    {
        try{
            int[] arr = null;
            div(4,0,arr); //调用了一个 声明抛出异常类型 的方法
        }catch(Exception e){
            System.out.println("出现异常了...");
            e.printStackTrace();
        }
        
    }


    public static void div(int a, int b,int[] arr) throws Exception,NullPointerException {
        if(b==0){
            throw new Exception(); //抛出一个异常对象...
        }else if(arr==null){
            throw new  NullPointerException();
        }
        int c = a/b;
        System.out.println("c="+c);
    }
}
class Demo
{
    public static void main(String[] args) 
    {
        int[] arr = null;
        div(4,0,arr);
    }

    public static void div(int a , int b,int[] arr){
        int c = 0;
        try{
            c = a/b;  //jvm在这句话的时候发现了不正常的情况,那么就会创建一个对应的异常对象。
            System.out.println("数组的长度:"+ arr.length);
        }catch(ArithmeticException e){
            //处理异常的代码....
            System.out.println("异常处理了....");
            System.out.println("toString:"+ e.toString());
        }catch(NullPointerException e){
            System.out.println("出现了空指针异常....");
        }catch(Exception e){  
            System.out.println("我是急诊室,包治百病!");
        }
        System.out.println("c="+c);
    }
}

自定义异常类

//自定义了一个没有网线的异常类
class NoIpException extends Exception{
    public NoIpException(String message){
        super(message);  //调用了Exception一个参数的构造函数
    }
}

class Demo 
{
    public static void main(String[] args) 
    {
        String ip = "192.168.10.100";
        ip = null;
        try{
            myQ(ip);  // 如果调用一个声明抛出异常类型的方法, 那么调用者必须要处理
        }catch(NoIpException e){
            e.printStackTrace();
            System.out.println(" 插上网线!");
        }
    }
    public static void myQ(String ip) throws NoIpException{
        if(ip==null){
            throw new  NoIpException("没有插网线啊,小白!");
        }
        System.out.println("正常显示好友列表..");
    }
}

异常体系

运行时异常: RuntimeException以及RuntimeException子类都是属于运行时异常
编译时异常: 除了运行时异常就是编译异常

上一篇 下一篇

猜你喜欢

热点阅读