zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    hihoCoder #1176 : 欧拉路·一 (简单)
    228 Summary Ranges 汇总区间
    227 Basic Calculator II 基本计算器II
    226 Invert Binary Tree 翻转二叉树
    225 Implement Stack using Queues 队列实现栈
    224 Basic Calculator 基本计算器
    223 Rectangle Area 矩形面积
    222 Count Complete Tree Nodes 完全二叉树的节点个数
    221 Maximal Square 最大正方形
    220 Contains Duplicate III 存在重复 III
  • 原文地址:https://www.cnblogs.com/rickyctbu/p/13296621.html
Copyright © 2011-2022 走看看