JavaSE基础05

多态

package com.OOP.demo08;

public class Person {

    public void work(){
        System.out.println("父亲白天要上班");
    }
    public void eat() {
        System.out.println("父亲中午吃烤肉");
    }
}
package com.OOP.demo08;

public class Student extends Person{
        public void course() {
            System.out.println("学生白天要上课");
        }

    @Override
    public void eat() {
        System.out.println("儿子中午吃米饭");
    }
}
package com.OOP;

import com.OOP.demo07.A;
import com.OOP.demo07.B;
import com.OOP.demo08.Person;
import com.OOP.demo08.Student;

public class Application {

    public static void main(String[] args) {
        //一个对象的实际类型是确定的
        // new Student();
        // new Person();
        //可以指向的引用类型就不确定了:父类的引用指向子类

        //Student 能调用的方法都是自己的或者继承父类的
        Student student01 = new Student();
        //Person 父类型,可以指向子类,但是不能调用子类独有的方法
        //换句话说:可以调用自己有而子类没有的方法
        Person person01 = new Student();

        //对象能执行那些方法,主要看对象左边的类型,和右边关系不大

        person01.work();
        person01.eat(); // 子类重写了父类的方法,调用子类的方法
        ((Student) person01).course();//父类中没有的方法,将父类对象强制转换成子类类型

        System.out.println();

        student01.work();// 子类中没有的方法,子类对象调用父类的方法
        student01.course();
        student01.eat();

    }
}
/*
多态的注意事项:
1. 多态是方法的多态,属性没有多态
2. 父类和子类,有联系:存在继承关系    类型转换异常!  ClassCastException!
3. 存在条件:    继承关系,方法需要重写,父类的引用指向子类类型     Father f1 = new Son();

    1. static 方法,属于类,不属于实例,不能被重写
    2. final 常量
    3. private 方法
 */

instancesof

instancesof

System.out.println(X instancesof Y); //输出结果为	布尔类型true、false
// 判断条件:X、Y之间存在联系:父子关系...
// X一般为子类	Y一般为父类

类型转换

package com.OOP.demo09;

public class Person {
    public void eat(){
        System.out.println("人吃饭");
    }
    public void drink(){
        System.out.println("人喝水");
    }
    public void sleep(){
        System.out.println("人睡觉");
    }
}
package com.OOP.demo09;

public class Student extends Person{
        public void run(){
            System.out.println("学生会在大课间进行跑步锻炼");
        }

    @Override
    public void eat() {
        System.out.println("学生中午在餐厅无法吃到好吃的饭菜");
    }
}
package com.OOP;

import com.OOP.demo09.Person;
import com.OOP.demo09.Student;

public class Application {

    public static void main(String[] args) {

        //低             转           高
        //子类            转           父类  向上转型
        Person person = new Student();

        person.eat();
        person.drink();
        person.sleep();

        //高         转           低
        //父类        转           子类      向下转型    强制转换
        //将这个对象转换成Student类型,我们就可以使用Student类型的方法了
        //但是在   高转低之后  转换过后的高类型的对象无法使用低类型中独有的方法
        //         父类转换成子类之后  转换过后的父类对象无法使用子类中独有的方法
        Student student = (Student) person;
        student.run();

        //组合式
        ((Student) person).run();

        Student student1 = new Student();
        Person person1 = student1; //父类的引用指向子类对象
    }
}
/*
1. 父类的引用指向子类对象
2. 把子类转换为父类:向上转型
3. 把父类转换成子类:向下转型
   向下转型的前提是已经发生了向上转型,向下转型是再次转回来而已
4. 方便方法的调用,减少重复代码,简洁
 */

Static关键字

package com.OOP.demo10;

//static    跟类一起加载
public class Student {
    private static int age; //静态变量  多线程
    private double score;   //非静态变量

    public static void run(){
        //在static方法中可以直接调用static方法,但是不能直接调用非static方法
        System.out.println("学生在大课间要进行跑步活动");
    }

    public void go(){
        run();  //static方法可以在非static方法中直接调用
        System.out.println("学生在课件或者体育课上可以选择性的进行跑圈运动锻炼身体");
    }

    public static void main(String[] args) {
        System.out.println(Student.age);

        Student student = new Student();

        System.out.println(student.score);
        System.out.println(student.age);

        new Student().go();
        Student.run();
        run();
    }
}
package com.OOP.demo10;

public class Person {
    // 2.匿名代码块,在构造方法之前执行
    // 可以通过匿名代码块赋初值
    {
        System.out.println("匿名代码块");
    }
    // 1. 静态代码块跟类一起执行,它是最早执行的,而且static只执行一次
    // 而其他的在对象一创建的时候,就执行一次匿名代码块,在往后执行构造方法
    static {
        System.out.println("静态代码块");
    }
    // 3. 构造方法
    public Person() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person person = new Person();
        System.out.println("===========");
        Person person1 = new Person();
    }

}
package com.OOP.demo10;
//静态导入包     可以省略类名不写,直接写方法名
import static java.lang.Math.PI;
import static java.lang.Math.random;

public class Text {
    public static void main(String[] args) {
        random();
        System.out.println(PI);
    }
}

final关键字注意:

被final修饰过后的类:会成为“最终类、终极类”,无法被继承

抽象类

package com.OOP;

//abstract  抽象类  extends   但是类有单继承的局限性      接口可以实现多继承
public abstract class Action {


    //约束--写框架--想要有人帮我们实现
    //abstract,抽象方法,只有方法名字,没有方法实现(方法体)
    public abstract void doSomething();

    /*
    抽象类特点:
    1. 抽象类不能new,只能靠它的子类去实现它:约束!
    2. 抽象方法里面也可以有普通方法
    3. 但是   一但类里面有一个抽象方法,该类就是抽象类

    思考:
    抽象类既然不能new,那它存在构造器吗?


    抽象类存在的意义?
    打游戏创建角色,如果角色非常复杂,反复创建的话会比较麻烦
    我们可以把角色的一些公有属性抽象出来
    每创建一个角色就去继承这些抽象类
    然后去自动重写它的一些方法
    提高开发效率!
     */
}
package com.OOP.demo10;

import com.OOP.Action;

//继承了抽象类的子类必须实现抽象类的所有方法,除非继承抽象类的子类也是抽象类,那就要它的子子类来实现
public class A extends Action {
    @Override
    public void doSomething() {
        System.out.println("约束--我只写框架--希望有人可以替我实现方法");
    }
}

接口

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范!自己无法写方法~~专业的约束! 约束与实现分离:面向接口编程

注意:接口的地位!

  • 接口就是规范,定义的是一直规则,体现了现实世界中 "如果你是...则必须能..." 的思想。 如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你是好人,则必须干掉坏人。如果你是坏人,则必须欺负好人
  • 接口的本质就是契约,就像我们人间的法律一样。制定好后大家都遵守
  • OO的精髓,是对 对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只是针对具备了抽象能力的语言(c++,java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象

声明类的关键字是:Class 声明接口的关键字是:interface 类与接口同样重要,甚至比类更重要

接口的作用

接口的作用:
        1. 约束
        2. 定义一些方法,让不同的人实现
        3. 方法都是 public abstract
        4. 属性都是 public abstract final
        5. 接口不能被实例化,接口中没有构造方法
        6. 通过implements关键字可以实现多个多个接口
        7. 必须要重写接口中的方法
package com.OOP.demo12;

//抽象的思维--java

//interface 接口定义的关键字,接口都需要实现类
public interface UserService {

    //尽量不要在接口中定义属性
    //在接口中定义的属性都是常量:public static final
    int AGE = 99;

    //接口中的所有定义的方法都是抽象的
    //自动加上public abstract,自己可以不用写,只写 方法返回值类型、方法名、参数列表
    //在接口中只能存在public ,其他任何权限修饰符都会报错
    int add(int number_a,int number_b);
    int subtract(int number_a,int number_b);
    int multiply(int number_a,int number_b);
    int division(int number_a,int number_b);
}
package com.OOP.demo12;

public interface TimeService {
    void timer();
}
package com.OOP.demo12;

//类 通过abstract关键字 将普通类声明成抽象类 通过extends关键字 可以继承抽象类,但是只能单继承
//类 通过implements关键字 可以实现接口,可以实现多个接口,可以利于接口实现多继承
//实现了接口的类,就需要重写接口中的全部方法

public class UserServiceImpl implements UserService,TimeService{
    @Override
    public int add(int number_a, int number_b) {
        int sum = 0;
        sum = number_a + number_b;
        return sum;
    }

    @Override
    public int subtract(int number_a, int number_b) {
        int Algorithms = 0;
        /* if (number_a > number_b){
            Algorithms = number_a - number_b;
        }else{
            Algorithms = number_b - number_a;
        }

         */

        /* Algorithms = number_a - number_b;
        if (Algorithms < 0) {
            Algorithms = -Algorithms;
        }else {
            Algorithms = Algorithms;
        }
 */

        Algorithms = Math.abs(number_a - number_b);

        if (number_a < number_b){
            Algorithms = -Algorithms;
        }else {
            Algorithms = Algorithms;
        }

        return Algorithms;
    }

    @Override
    public int multiply(int number_a, int number_b) {
        int Algorithms = 0;
       /* Algorithms = number_a * number_b;

        if (number_a == 0 && number_b == 0){
            System.out.println("您输入的数字没有计算意义");
        }
        if (number_a == 0 || number_b == 0) {
            Algorithms = 0;
        }
        */
        Algorithms = number_a * number_b;

        if (number_a == 0 || number_b == 0){
            Algorithms = 0;
        }

        return Algorithms;
    }

    @Override
    public int division(int number_a, int number_b) {
        int Algorithms = 0;

        while (number_b != 0) {
            Algorithms = number_a / number_b;
            break;
        }
        if (number_b == 0){
            System.out.println("0不能作除数");
        }
        return Algorithms;
    }

    @Override
    public void timer() {

    }
}
package com.OOP;

import com.OOP.demo12.UserServiceImpl;

public class Application {

    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        System.out.println(userService.subtract(30, 20));
        System.out.println(userService.multiply(1, 2));
        System.out.println(userService.division(10, 0));
    }
}

N种内部类

package com.OOP.demo13;

public class Outer {

    private int id = 10;
    public void out(){
        System.out.println("这是外部类的方法");
    }
    //成员内部类
    //成员内部类加上static就是静态内部类
    //静态内部类无法获得外部类的私有属性,除非把外部类的属性也改为static
    public class Inner {
        public void in(){
            System.out.println("这是内部类的方法");
        }

        //通过内部类获得外部类的私有属性
        public void getID() {
            System.out.println(id);
        }

        public void getOut(){
            out();
        }

    }

}

//一个java类中可以有多个class类,但是只能有一个public class类
class A {
    public static void main(String[] args) {
        //局部内部类
        //声明在方法中的变量成为局部变量,声明在方法中的类称为局部内部类
        class Inner {

        }
    }
}
package com.OOP.demo13;

public class Text {
    public static void main(String[] args) {
        //有对象名的初始化
        Apple apple = new Apple();

        //没有对象名字的初始化  匿名内部类
        //匿名对象的使用,不用将实例保存在变量中
        new Apple().eat();

		//匿名内部类
        new UserService(){
            @Override
            public void hello() {

            }
        };
    }
}

class Apple {
    public void eat() {
        System.out.println("1");
    }

}

interface UserService {
    void hello();
}
package com.OOP;

import com.OOP.demo13.Outer;

public class Application {

    public static void main(String[] args) {
        Outer outer = new Outer();

        //通过这个外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();

        inner.in();
        inner.getID();
        inner.getOut();
    }
}

异常机制

异常处理机制

1. 抛出异常

package com.exception;

public class Text03 {
    public static void main(String[] args) {
        int number_a = 10;
        int number_b = 0;

        //Ctrl + Alt + T  快捷键生成代码块包裹代码
        try {
            if (number_b == 0){
                throw new ArithmeticException(); //主动抛出异常
            }
            System.out.println(number_a/number_b);
        } catch (Exception e) {
            System.out.println("除数不能为0");
            e.printStackTrace();    //打印错误的栈信息
        } finally {
            System.out.println("除数不能为0,请重新出入");
        }
    }
}
package com.exception;

public class Text04 {
    public static void main(String[] args) {

        try {
            new Text04().text(2,0);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }

    //假设这个方法中,处理不了这个异常。我们在  方法上抛出异常 使用throws关键字上抛异常
    public void text(int a,int b) throws ArithmeticException{
        if(b == 0){ //throw, throws
            throw new ArithmeticException(); //使用throw关键字主动抛出异常,一般在方法中使用
        }
        System.out.println(a/b);
    }
}

2. 捕获异常

package com.exception;

public class Text {

    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        try {   //try监控区域
            System.out.println(a/b);
        }catch (ArithmeticException e){     //catch 捕获异常
            System.out.println("程序出现异常,0不能作除数");
        }finally {  //处理善后工作,可以不写,但是try,catch必须写
            System.out.println("finally");
        }

        //finally一般用于最后     IO流的资源关闭  
        //而且在finally执行完成后再进行报错爆红
    }
}
package com.exception;

public class Text {

    public static void main(String[] args) {
        try {   //try监控区域
            new Text().a();
        }catch (Throwable e){     //catch 捕获异常
            System.out.println("程序出现异常,程序无法终止");
        }finally {  //处理善后工作,可以不写,但是try,catch必须写
            System.out.println("finally");
        }

        //finally一般用于最后     IO流的资源关闭
        //而且在finally执行完成后再进行报错爆红
    }

    public void a(){
        b();
    }
    public void b(){
        a();
    }
}
package com.exception;

public class Text {

    public static void main(String[] args) {

        int a = 1;
        int b = 0;

        try {   //try监控区域
            System.out.println(a/b);
        }catch (Error e){     //catch(想要捕获的异常类型) 捕获异常
            System.out.println("Error");
        }catch (Exception e){
            System.out.println("Exception");
        }catch (Throwable t){
            System.out.println("Throwable");
        }finally {  //处理善后工作,可以不写,但是try,catch必须写
            System.out.println("finally");
        }

        //finally一般用于最后     IO流的资源关闭
        //而且在finally执行完成后再进行报错爆红
    }

    public void a(){
        b();
    }
    public void b(){
        a();
    }
}
//假设要捕获多个异常,要从小到大进行捕获
//catch捕获的异常的范围  从上到下 依次扩大,不能颠倒
package com.exception;

public class Text02 {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        //Ctrl + Alt + T  快捷键生成代码块包裹代码
        try {
            System.out.println(a/b);
        } catch (Exception e) {
            System.out.println("除数不能为0");
            System.exit(0);   //如果出现异常,退出程序
            e.printStackTrace();    //打印错误的栈信息
        } finally {
            System.out.println("除数不能为0,请重新出入");
        }
    }
}

3.异常处理的五个关键字

try,catch,finally,throw,throws

自定义异常类

package com.exception.demo02;
//自定义的异常类   要继承Exception类
public class MyException extends Exception {
    //传递数字 > 10
    private int detail;

    public MyException(int a) {
        this.detail = a;
    }

    //toString: 异常的打印信息
    @Override
    public String toString() {
        return "MyException{"  + detail + '}';
    }
}
package com.exception.demo02;

public class Text {

    //可能会存在异常的方法
    public static void text(int a) throws MyException {

        System.out.println("传递的参数为 " + a);

        if (a > 10){
            throw new MyException(a); //抛出
        }

        System.out.println("OK");
    }

    public static void main(String[] args) {
        try {
            text(1);
        } catch (MyException e) {
            //增加一些处理异常的代码块
            //if(a > 10){
            //a--;
            //}
            System.out.println("MyException =>" + e);
        }

    }
}

实际工作当中的异常经验总结

  • 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
  • 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
  • 对于不确定的代码,也可以加上try-catch,处理潜在的异常
  • 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
  • 具体如何处理异常,要根据不同的业务需求和异常类型去决定
  • 尽量添加finally语句块去释放占用的资源
posted @ 2025-02-26 16:47  LYQ学Java  阅读(25)  评论(0)    收藏  举报