java学习笔记(二)

1、父类到子类的转换

向下转换(强制类型转换)

Pet pet = new Dog("aa", 20);
Dog dog = (dot) new Pet()

报错,必须转换为父类指向的真实子类类型

 2、接口

 java中的继承关系是单继承,如果拥有多个父类的时候,可以考虑使用接口进行实现

  java中的接口具备广泛的使用

  用法:

    1、使用interface来修饰

    2、接口中可以包含多个方法,且方法跟抽象类中的抽象方法一致,可以不写实现,子类在实现的时候必须要实现代码逻辑

    3、子类实现接口实现使用implements关键字

  特征:

    1、接口中的所有方法都是抽象方法,不能包含方法的实现

    2、接口中的所有方法与常量的访问修饰权限都是public,不写并不是默认访问权限,而是public, 系统默认会添加public;

    3、接口不能被实例化

    4、接口的子类必须实现接口中的所有方法,跟抽象类有所不同,抽象类中的抽象方法必须被子类实现

    5、子类可以实现多个接口

    6、接口中的变量都是静态常量(相当于加上static final)

 接口:

package com.yfbill.test;

public interface ITest {
    //静态常量
    public static final String abc = "are you ok???";
    //需要子类实现的方法
    public int getUniqueId();
    public String getName();
}

实现子类:

package com.yfbill.utils;

import com.yfbill.test.ITest;

public class Test implements ITest {   //如果是多个接口的话,用“,”来隔开

    @Override
    public int getUniqueId() {
        return 0;
    }

    @Override
    public String getName() {
        return Test.abc;
    }
}

抽象类中可以实现接口,并且不实现接口中的方法,而接口只能继承接口,不能实现接口

在实际的项目开发过程中,如果可以使用接口,尽量使用接口,将单继承的父类留在最关键的地方

3、内部类 

  一个java文件中可以包含多个class,但是只能有一个public class

  如果一个类定义在另一个类的内部,此时可以称之为内部类

使用:

  创建内部类的时候,跟之前的方法不一样,需要在内部类的前面添加外部类进行修饰

   InnerClassDemo.InnerClass inner = new InnerClassDemo().new InnerClass();

特点:

  1、内部类可以方便的访问外部类的私有属性

  2、外部类不能访问内部类的私有属性,但是如果创建了内部类的对象, 此时可以在外部类中访问私有属性

  3、内部类不能定义静态属性或静态方法

  4、当内部类和外部类具有相同的私有属性的时候,在外部类中访问的时候,可以直接访问内部类的属性,如果需要访问外部类的属性,那么需要添加  外部类名.this.属性。

内部类以及外部类(以下是成员内部类)

package com.yfbill.test;

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void say() {

        System.out.println(this.name + "可以say anything");
    }

    public void printInnerClass() {
        Teacher t = new Teacher(1122);  //在外部类中访问内部类,必须实例化出内部类,此时的内部类,可以访问外部类的属性
        t.info();   //会输出 name:bill
    }

    public class Teacher {                 //内部类
        private int count;

        public Teacher(int count) {
            this.count = count;
        }

        public String getCount() {

            return "the teacher's count is " + this.count;
        }

        public void info() {

            System.out.println("name:" + Person.this.name);
        }
    }
}

调用:

package com.yfbill.test;

public class Test {
    public static void main(String[] args) {
        Person p = new Person("bill", 30);
        p.say();    //输出 bill可以say anything
        p.printInnerClass();  //输出 name:bill

        Person.Teacher t = p.new Teacher(9527);
        System.out.println(t.getCount());  //输出 the teacher's count is 9527
        t.info();  //输出 name:bill
    }
}

 分类

  1、匿名内部类 =》 当定义了一个类,实现了某个接口的时候,在使用过程中只需要使用一次,没有其他用途,其实考虑到代码编写的简洁,可以考虑不创建具体的类,而采用new interface(){ 添加未实现方法 }  叫做匿名内部类

package com.yfbill.test;

//定义接口
interface IPerson {
    public void run ();
}

//定义类
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void say() {
        //匿名内部类,匿名的实现了IPerson接口
        //隐藏的class声明
        new IPerson() {

            @Override
            public void run() {
                System.out.println("我的名字是" + Person.this.name + "我今年的年龄是:" + Person.this.age + "我很喜欢跑步");
            }
        }.run();  //直接调用方法
    }
}

调用:

package com.yfbill.test;

public class Test {
    public static void main(String[] args) {
        Person p = new Person("bill", 30);
        p.say();
    }
}

  2、静态内部类 =》 关键字static可以修饰成员变量、方法、代码块、其实还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类,静态内部类和非静态内部类之间存在一个最大的区别,非静态内部类在编译完成之后会隐含的保存着一个引用,该引用是指向创建它的外围类,但是静态类没有。没有这个引用就意味着:

  1.静态内部类的创建不需要依赖外部类可以直接创建。

  2.静态内部类不可以使用任何外部类的非static类(包括属性和方法),但可以存在自己的成员变量。

package com.yfbill.test;

public class Person {
    private String password;
    private static String username = "admin";

    public static String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    //静态内部类
    public static class Teacher {
        private int code;
        //静态内部类的构造方法
        public Teacher (int code) {
            this.code = code;
        }
        //静态内部类不能访问外部类的非静态方法和属性
        public void showCode () {
            System.out.println("code:" + this.code);
            System.out.println(Person.username);
            System.out.println(Person.getUsername());
        }
    }

    public static void main(String[] args) {
        Person p = new Person();
        //静态内部类的实例化以及调用方式
        Person.Teacher t = new Person.Teacher(9527);
        t.showCode();
    }
}

   3、方法内部类 =》 方法内部类顾名思义就是定义在方法里的类

  1.方法内部类不允许使用访问权限修饰符(public、private、protected)均不允许。

  2. 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问 (换句话说其他方法或者类都不知道有这个类的存在)方法内部类对外部完全隐藏,出了创建这个类的方法可以访问它,其他地方均不能访问。
  3. 方法内部类如果想要使用方法形参,该形参必须使用final声明(JDK8形参变为隐式final声明)

class Outer{
    private int num =5;
    //普通方法
    public void dispaly(int temp)
    {
        //方法内部类即嵌套在方法里面
        class Inner{
            public void fun()
            {
                System.out.println(num);
                temp++;
                System.out.println(temp);
            }
        }
        //方法内部类在方法里面创建
        new Inner().fun();
    }
}
public class Test{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.dispaly(2);
    }
}

4、异常处理

 java中的异常处理是通过5个关键字来实现的: try   catch    finally   throw    throws;

程序在运行过程中如果出现了问题,会导致后面的代码无法正常运行,而使用异常机制,可以对异常情况进行处理,同时后续代码会继续执行。

异常处理方式

  1、捕获异常

    try{ 代码逻辑 }catch( Exception e ) { 异常处理逻辑 }

package com.yfbill.test;

import java.util.Scanner;

public class Person {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        try{
            System.out.println("请输入被除数:");
            int num1 = scan.nextInt();              //假如本程序出现异常,那么该行代码下的的不能被执行,但是异常外的代码会被执行
            System.out.println("请输入除数");
            int num2 = scan.nextInt();
            System.out.println(String.format("结果是:%d", num1/num2));
        }catch(Exception e) {
            System.out.println("出现异常");
            e.printStackTrace();        //打印堆栈信息(常用)
            System.out.println(e.getMessage()); //打印错误提示
        }
        System.out.println("感觉使用本程序");
    }
}

注意:在使用的过程中,尽量在少的代码处且易发生异常的地方使用异常捕获

   2、try{ 代码逻辑 }catch( Exception e ) { 异常处理逻辑 }catch(具体的异常); =》 可以针对每一个具体的异常做更丰富的处理

public class DealException
{
    public static void main(String args[])
    {
        try
        //要检查的程序语句
        {
            int a[] = new int[5];
            a[0] = 3;
            a[1] = 1;
            //a[1] = 0;//除数为0异常
            //a[10] = 7;//数组下标越界异常
            int result = a[0]/a[1];
            System.out.println(result);
        }
        catch(ArrayIndexOutOfBoundsException ex)
        //异常发生时的处理语句
        {
            System.out.println("数组越界异常");
            ex.printStackTrace();//显示异常的堆栈跟踪信息
        }
        catch(ArithmeticException ex)
        {
            System.out.println("算术运算异常");
            ex.printStackTrace();
        }
        finally
        //这个代码块一定会被执行
        {
            System.out.println("finally语句不论是否有异常都会被执行。");
        }
        System.out.println("异常处理结束!");
    }
}

 注意:在使用多重catch的时候要注意多重异常的顺序,将子类异常放在异常最前面,而父类放在异常的后面

   3、finally   => 在程序运行过程中,如果处理异常的部份包含finally的处理,那么无论代码是否发生异常,finally中的代码总会执行

    finally包含的处理逻辑: 1:IO流的关闭操作一般设置在finally中; 2、数据库的连接关闭操作设置在finally中

package com.yfbill.test;


public class Person {
    private static int init() {
        int num = 10;
        try {
            num += 20;
            return num;
        } catch(Exception e) {
            e.printStackTrace();
            return num - 10;
        } finally {
            System.out.println("this is finally"); //会输出结果
//            return num + 30;
        }
    }
    public static void main(String[] args) {
        System.out.println(Person.init());  //返回30,如果finally中的return 存在,那么就返回60,finally中的代码会被执行
    }
}

   4、抛出异常:在异常情况出现的时候,可以使用try...catch...finally的方式对异常进行处理,除此之外,可以将异常向外抛出 

          1、在方法调用过程中可能存在N多个方法的调用,此时假如每个方法中都包含了异常情况,

          那么就需要在每个方法中进行try...catch...,另外一种比较简单的方式,就是在方法的最外层调用处理一次即可,

          使用throws的方法,对所有执行过程中的所有方法出现的异常进行统一集中处理。

          2、如何判断是使用throws还是使用try...catch...,最稳妥的方式是在每个方法中都进行异常处理,偷懒的方式是在判断在整个调用过程中,最外层的调用方法是否对异常处理,如果有就直接使用throws,如果没有就直接使用try...catch...进行处理  

package com.yfbill.test;

public class Person {
    public void init () {   //在最外层调用的时候使用try...catch...进行处理
        try{
            this.test3();
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("这个是执行完成了哈");
        }

    }
    private void test1() throws Exception {
        System.out.println(1/0);
    }
    private void test2() throws Exception {
        this.test1();
        System.out.println(1/0);
    }
    private void test3() throws Exception {
        this.test2();
        System.out.println(1/0);
    }
    public static void main(String[] args) {
        Person p = new Person();
        p.init();
    }
}

   5、常见的异常类型

异常类型 说明
Exception 异常层次结构的父类
ArithmeticException 算术错误类型,如0作除数
ArrayIndexOutOfBoundsException 数组下标越界
NullPointerException 尝试访问null对象成员
ClassNotFoundException 不能加载所需的类
IllegalArgumentException  方法接收到非法参数 
 ClassCastException  对象强制类型转换错误 
 NumberFormatException 数字格式转换异常,如果把abc转成数据 

 

    

   6、抛出异常

package com.yfbill.test;

public class Person {
    public void init () {
        try{
            this.test1();
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("这个是执行完成了哈");
        }
    }
    private void test1() throws Exception {
        throw new Exception("现在发生错误了哈");  //主动抛出异常
    }

    public static void main(String[] args) {
        Person p = new Person();
        p.init();
    }
}

 也可以主动抛出具体的异常

  7、可以自已定义异常类

package com.yfbill.test;

public class TestException extends Exception{
    public TestException () {
        super();
    }

    public TestException (String s) {
        super(s);
    }
}
原文地址:https://www.cnblogs.com/rickyctbu/p/13296621.html