Java面向对象

Java面向对象

  • 面向对象编程 ( Object-Oriented Programming, OOP )
  • 面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据。

1、面向对象三大特性

  • 封装

    • 程序追求 高内聚,低耦合;

    • 该露的露,改藏的藏;

    • 类封装,属性私有,提供get/set方法访问。

  • 继承

    • 关键字 extends;

    • 类与类之间只能单继承,接口之间可以多继承;

    • 子类可以重写父类中的方法。

      • 重写的方法名和形参列表必须相同;
      • 方法权限修饰符,范围可以扩大但不能缩小;
      • 方法抛出的异常,范围可以被缩小,但不能扩大。
      class A{
          public void test(){
      
          }
      }
      
      class B extends A{ // B类继承A类
          @Override
          public void test(){ // B类重写A类中的test方法
      
          }
      }
      
  • 多态

    一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。

    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
    // 以上面B类继承A类为例
    A b = new B();
    b.text(); // 子类重写了父类方法,则调用子类重写的方法,如果没有重写父类方法,则调用父类的方法。这就是方法的多态。
    

2、类

  • 成员变量(属性)
  • 构造器
  • 方法

3、static关键字

  • static可以用于修饰成员变量、方法、内部类和代码块;

  • static修饰的变量和方法,会随着类的加载而加载,类的消失而消失。存在于方法区中,别所有线程共享;

  • static修饰的变量和方法属于类,可以直接通过类来调用;

  • static代表静态,由于非静态方法是随着对象的实例化而加载,存在于堆中,因此非静态方法内部是无法调用静态方法和变量;

  • static修饰的方法也不能被子类重写;

  • static 修饰的代码块表示静态代码块,当 Java 虚拟机(JVM)加载类时,就会执行该代码块,只会被执行一次。

  • 静态导入包

    import static java.lang.Math.PI; // 可以导入类中的属性和方法
    

4、final关键字

  • final可以用于修饰类,变量,方法;
  • final修饰类,该类不能被继承, final类中的方法默认是final的;
  • final修饰成员变量,该成员变量需要被赋值,且赋值后值无法再改变;
  • final修饰成方法,该方法无法被子类重写;
  • final修饰方法形参,该形参的值无法再改变。

5、权限修饰符

权限修饰符用于修饰属性、方法和构造器,限制其被访问的范围。

修饰符 本类内部 同一个包 子类 任何地方
public
protected
(缺省)
private

6、代码块

public class A{
    {
        System.out.println("匿名代码块");
    }
    
    static {
        System.out.println("静态代码块");
    }
     
    public A(){
        System.out.println("构造方法");
    }
}

/*
 执行顺序:静态代码块 -> 匿名代码块 -> 构造方法
 静态代码块会在类被加载时执行一次;
 匿名代码块和构造方法会在类每次实例化时执行。
*/

7、抽象类

  • 使用 abstract 关键字修饰类;
  • 使用 abstract 关键字修饰的方法叫抽象方法,抽象类中可以包抽象方法和普通方法;
  • 抽象类不能被实例化(不能new),只能被子类去实现;
  • 子类继承抽象类,则必须实现抽象类中的所有抽象方法,否则子类也必须申明为抽象类;
  • 抽象类可以有构造方法。
public abstract class A{
    public A(){
        System.out.println("构造方法");
    }
    
    public abstract void test(); //抽象方法没有方法体 
}

8、接口

  • 使用 interface 关键字去申明;
  • 接口的本质是锲约(规范),接口中只能包含抽象方法,方法都是 public abstract 的;
  • 接口中的变量必须是 public static final 的;
  • 接口不能有构造方法;
  • 接口只能被其他类实现,通过 implement 关键字,实现接口的类必须重写接口中的方法;
  • 接口可以被多实现,多个接口间用逗号间隔。
public interface B{
    public abstract void test();
}

class A implement B{
    @Override
    public abstract void test(){ // 重写实现接口中定义的方法
        
    }
}

9、内部类

成员内部类

public class Outer {

    public void out(){
        System.out.println("这是外部类方法");
    }

    public class Inner{ // 成员内部类
        public void in(){
            System.out.println("这是内部类方法");
        }
    }
}

public class Application {

    public static void main(String[] args) {
        Outer outer = new Outer();
		// 内部类实例化	
        Outer.Inner inner = outer.new Inner();
        inner.in();
    }
}

静态内部类

public class Outer {

    public void out(){
        System.out.println("这是外部类方法");
    }

    public static class Inner{ // 静态内部类
        public void in(){
            System.out.println("这是内部类方法");
        }
    }
}

public class Application {

    public static void main(String[] args) {
		// 内部类实例化	
        Outer.Inner inner = new Outer.Inner();
        inner.in();
    }
}

局部内部类

public class Outer {

    public void method(){
        class Inner{ // 局部内部类
            public void in(){
                System.out.println("这是局部内部类方法");
            }
        }
        Inner inner = new Inner();
        inner.in();
    }
}

匿名内部类

abstract class Person { // 可以是抽象类也可以是接口
    public abstract void eat();
}

public class Demo {
    public static void main(String[] args) {
        Person p = new Person() { // 匿名内部类
            @Override
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

10、异常

  • Java异常根类 Throwable ,Throwable 包含子类 错误-Error 和 异常-Exception
  • Error:是程序中无法处理的错误,表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时JVM出现问题。通常有Virtual MachineError(虚拟机运行错误)、NoClassDefFoundError(类定义错误)等。比如说当jvm耗完可用内存时,将出现OutOfMemoryError。此类错误发生时,JVM将终止线程。非代码性错误。因此,当此类错误发生时,应用不应该去处理此类错误。
  • Exception:程序本身可以捕获并且可以处理的异常。
    • 运行时异常(RuntimeException):表示JVM在运行期间可能出现的错误。编译器不会检查此类异常,并且不要求处理异常,比如用空值对象的引用(NullPointerException)、数组下标越界(ArrayIndexOutBoundException)。此类异常属于不可查异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。
    • 非运行时异常/检查性异常:编译器会检查此类异常,如果程序中出现此类异常,比如说IOException,必须对该异常进行处理,要么使用try-catch捕获,要么使用throws语句抛出,否则编译不通过。

异常处理

可以处理 Exception 异常。

  • 抛出异常

    // 抛出异常,在方法申明后使用throws关键字抛出异常类型
    // 被抛出的异常需要在方法的调用处捕获处理,或者继续被抛出。
    // 抛出多个异常用逗号间隔
    public void method() throws Exception{
        int a = 1, b = 0;
        double c = a / b; // 可能会出现异常代码
    }
    
    /* 还可以使用 throw 主动抛出异常 */
    public void method2() throws Exception {
        int a = 1, b = 0;
        double c = 0.0;
        if(b != 0)
            c = a / b;
        else
            throw new Exception(); // 主动抛出异常
    }
    
  • 捕获异常

    // 捕获异常使用try-catch-finally
    // try-catch-finally 中,catch 和 finally 语句块可以省略其中一个。
    public void method(){
        int a = 1, b = 0;
        try { // 捕获异常
            double c = a / b; // 可能会出现异常代码
        } catch (Exception e) {
            // 捕获到异常后执行的代码逻辑,写在这里
        } finally{
            // 写在这里的代码,不论有没有捕获到异常,在最后都会被执行
        }
    }
    

自定义异常类

  • 只需要继承Exception类即可
// 自定义异常类
public class MyException extends Exception {

    private String detail;

    public MyException(String detail){
        this.detail = detail;
    }

    @Override
    public String toString() {
        return "MyException{ 值不能为:" + detail + "'}";
    }
}

public class Test {

    public void method() throws MyException {
        int a = 11;
        if(a > 10)
            throw new MyException(a); // 抛出自定义的异常
        else
            System.out.println("OK");
    }
}
posted @ 2021-05-03 15:33  金盛年华  阅读(98)  评论(0)    收藏  举报