Java基础 (四)

oop

  1. 初始面向对像

    面向过程&面向对象

    ​ 面向过程思想,第一步做什么,第二步做什么。。。。

    ​ 面向过程适合处理一些较为简单的问题

    面向对象思想

    ​ 分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后才对某个分类下的细节进行面向过程的思考

    面向对象适合处理复杂的问题,适合处理复杂问题,适合处理需要多人协作的问题

    对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,任然需要面向过程的思路去处理

    什么是面向对象(OOP):

    ​ 本质:以类的方式组织代码,以对象的组织(封装)数据

    ​ 抽象:编程思想!持续的学习,貌似顿开,多实践,多测试大脑中的想法!实践出真知

    ​ 三大特性:

    			1. 封装 
       			2. 继承 extends
       			3. 多态 static
    

    从知识角度考虑是先有对象后有类。对象,是具体的事物,类,是抽象的,是对对象的抽象

    从代码运行角度考虑是先用类后有对象。类是对象的模板

  2. 方法回顾和加深

    • 方法的定义
    1. 修饰符

      • 私有访问修饰符-private

      • 公有访问修饰符-public

      • 受保护的访问修饰符-protected

      • 默认访问修饰符-不使用任何关键字

      static 修饰符

      default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
      
      private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
      
      public : 对所有类可见。使用对象:类、接口、变量、方法
      
      protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
      
    2. 返回类型

    3. break:break跳出switch,结束循环和return的区别,return:返回一个结果

    4. 方法名:注意规范就行,,见名知意

    5. 参数列表 :(参数类型 ...参数)

    6. 异常抛出:数组下标越界

    • 方法的调用:

      1. 静态方法

        //调用静态方法
        //类名.方法名
        
      2. 非静态方法 :

        //调用非静态方法
        //使用new关键字创建对象
        //对象类型   对象名=new  对象类型()
        
      3. 形参和实参

      4. 值传递和引用传递:引用传递本质还是值传递

      5. this关键字:表示当前操作的对像

  3. 对象(类)的创建分析

    • 使用new关键字创建对象

    • 使用new关键字的时候,除了分配内存空间之外,还会给创建好的对象进行初始化以及对类中的构造器的调用

    • 类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的,并且构造器有以下两个特点:

      1. 必须和类的名字相同
      2. 必须没有返回值类型
    • 构造器必须掌握

      默认是一个无参的构造函数

      //使用new关键字创建对象,本质是在调用构造器
      //用来初始值
      public Demo3() {
      }
      //有参数的构造:一旦定义了有参构造,无参就必须显示定义(相当于方法的重载)
      public Demo3(String string) {
      }
      
      //alt  +  insert  快速生成有参构造
      

    类与对象的关系:

    ​ 类是一种抽象的类型

    ​ 对象是抽象概念的具体实例

  4. 面向对象的三大特性

    	封装(数据的隐藏):
    ​		高内聚,低耦合:高内聚:类内部的数据操作测细节自己完成,不允许外部干涉。低耦合:仅仅暴露少量方法给外部使用
    ​		通常,应该禁止直接访问一个对象中的数据的实际表示,而应通过操作接口来访问,这才称为信息隐藏。
    ​		属性私有,get/set
    ​	继承:
            /*继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模.
    			extands的意思是扩展。子类是父类的扩展
    			java中只有单继承,没有多继承。(一个儿子一个爸爸,一个爸爸多个儿子)
    			继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合,聚合等
    			继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
    			子类和父类之间,从意义上讲应该具有is  a的关系
    			object类
    			*/
    			super
    				//注意点1.super调用父类的构造方法。,必须在构造方法的第一个
        			//2.super必须只能出现在子类的方法或者构造方法中
        			//3.super和this不能同时调用构造方法
                 this
        			//两者代表的对象不同:
        			/*
        			this:本身调用者的对象
        			super:代表父类对象的引用
        			前提:
        				this: 没有继承也可以使用
        				super:只能在继承条件中使用
        				
        			构造方法:
        				this():本类的构造
        				super():父类的构造
        			*/
        			
    			方法重写
                 /*
                 需要有继承关系:子类重写父类方法!
                 1.方法名必须相同
                 2.参数列表必须相同
                 3.修饰符:范围可以扩大:public→→→protected→→→→default→→→→private
                 4.抛出的异常:范围,可以被缩小,但不能被扩大:classNotFoundException→→→→Exception(大)(X)
                 */
            重写:子类的方法名必须和父类一样,方法体不同!!
            为什么需要重写?
            			父类的功能子类不一定需要,或不一定满足!
            //Alt+Insert:Override 重写
            
    
    ​	多态:
            /*
            动态编译:类型:可扩展性
            即同一个方法可以可以根据发送的对象的不同而采用多种不同的行为方式
            一个对象的实际类型是确定的,但可以指向对像的引用的类型有很多
            多态存在的条件:
            			有继承关系
            			子类重写父类的方法
            			父类引用子类指向子类对象
            注意:多态是方法的多态,属性没有多态性。
            instanceof   (类型转换) 引用类型
            */
            注意事项:
            /*
            1.多态是方法的多态,属性没有多态
            2.父类和子类,有联系,类型转换异常
            3.存在条件:继承关系,方法需要重写,父类引用指向子类对象!Father F=new  Son();
          不能重写的方法:
            		1.static 方法,属于类,它不属于实列
            		2.final 常量:
            		3.private方法:私有的
            */
        
            
    
  5. instanceof和类型转换
    instanceof:可以判断两个类是否存在父子关系

           存在父子关系
           //Object >  String
           //Object  >  Person   >son
           //Object  >  Person   >son2
          Object object =new son();
       
           //System.out.println(x instanceof y);//编译能否通过  x  与  y是否存在父子关系
           System.out.println((object instanceof son));//true
           System.out.println((object instanceof son2));//false
           System.out.println((object instanceof Person));//true
           System.out.println((object instanceof Object));//true
           System.out.println((object instanceof String));//False  String是Java的Lib标签下的
           System.out.println("------------");
           Person person =new son();
           System.out.println((person instanceof son));//true
           System.out.println((person instanceof son2));//false
           System.out.println((person instanceof Person));//true
           System.out.println((person instanceof Object));//true
       
          // System.out.println((person instanceof String));//编译就报错
           System.out.println("------------");
           son s=new son();
           System.out.println(( s instanceof son));//true
           //System.out.println(( s instanceof son2));//false
           System.out.println(( s instanceof Person));//true
           System.out.println(( s instanceof Object));//true
           //System.out.println(( s instanceof String));//False
    
    
    ststic总结:
    
    ```java
    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) {
           System.out.println(random());
           System.out.println(PI);
       }
    }
    
    package com.OOP.Demo10;
    
    
    public final class Student {
        private static int age;//静态变量  通过类名.属性进行访问
        private  double score;//非静态变量
    
        public static void main(String[] args) {
    
           /*
            Student s1=new Student();
            System.out.println(Student.age);
            //System.out.println(Student.score);
            System.out.println(s1.age);
            System.out.println(s1.score);
    
            Student.go();
            //Student.run();
    
            */
    
            Student s1=new Student();
            System.out.println("=====================");
            Student s2=new Student();
    
        }
    
        //匿名代码块     2
        {
    
            System.out.println("匿名代码块");
        }
        //最早执行的和类一块加载  1
        //静态代码块
        static {
            //静态代码块
            System.out.println("静态代码块");
        }
    
        public Student() {
            //                   3
            System.out.println("构造方法");
        }
    
        public void run(){
            System.out.println("Run");
        }
        public static void go(){
            System.out.println("GO");
        }
    }
    
    
  6. 抽象类和接口

    抽象类:

    • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法,如果修饰类,那么该类就是抽象类

    • 抽象类中可以没有抽象方法,但是由抽象方法的类一定要申明为抽象类

      • 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的
    • 抽象方法,只有方法的声明,没有方法的实现,他是用来让子类实现的

    • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象的方法,否则该子类也要申明为抽象类

    • package com.OOP.Demo11;
      
      //抽象类的所有方法,继承了他的子类,都必须要实现它的方法
      public  class A extends Action {
          @Override
          public void doSomething() {
      
          }
      }
      
      package com.OOP.Demo11;
      
      //abstract: 抽象类 : 本质是类  extends  :单继承    (接口可以多继承)
      public abstract class Action {
          //约束-有人帮我们实现
          //abstract  , 抽象方法,只有方法名字,没有方法的实现!
          public abstract void doSomething();
          /*
          特点:
          1.不能使用new这个抽象类,只能靠子类去实现它:约束
          2.抽象类中可以写普通方法,只能靠子类去实现它:约束
          3.抽象方法必须在抽象类中,只能靠子类去实现它:约束
          抽象的抽象:约束
          4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
           */
      
      }
      
      package com.OOP.Demo11;
      
      //abstract: 抽象类 : 本质是类  extends  :单继承    (接口可以多继承)
      public abstract class Action {
          //约束-有人帮我们实现
          //abstract  , 抽象方法,只有方法名字,没有方法的实现!
          public abstract void doSomething();
          /*
          特点:
          1.不能使用new这个抽象类,只能靠子类去实现它:约束
          2.抽象类中可以写普通方法,只能靠子类去实现它:约束
          3.抽象方法必须在抽象类中,只能靠子类去实现它:约束
          抽象的抽象:约束
          4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
           */
      
      }
      

    接口:

    • 普通类:只有具体实现

    • 抽象类:具体实现和规范(抽象方法)都有

    • 接口:只有规范,自己无法写方法,专业抽象,专业约束!约束和实现分离:面向接口编程

    • 接口就是规范,定义的是一组规则。

    • 接口的本质是契约,就像法律,制定好以后,大家遵守

    • oop的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备抽象能力的语言(Java ,c++ ,C#)就是因为设计模式所研究的,实际上是如何合理的抽象。

    • 申明类的关键字是:class 申明接口的关键字是:interface

    • 作用:
          1.约束
          2.定义一些方法让不同的人实现
          3.public  abstract  :接口中定义的方法都是抽象的
          4.public static final:接口中的属性都是常量
          5.接口不能被直接实列化,接口不死类,接口没有构造方法
          6.implemnets:定义接口,可以实现多个接口
          7.实现接口,必须要实现接口里面的抽象方法
      
      package com.OOP.Demo12;
      
      //抽象的思维,
      // interface 定义接口的关键字  接口都需要有实现类
      public interface UserService {
          //属性默认,常量 final
          //public static final int AGE=90;
          int AGE=90;
      
          //接口中所有定义的方法其实都是抽象的   public abstract
          void add(String name);
          void delete(String name);
          void update(String name);
          void query(String name);
      
      }
      
      package com.OOP.Demo12;
      
      //implements  关键字   实现接口的类定义,
      public class UserServiceImp1 implements UserService,TimeService {
          public UserServiceImp1() {
          }
      
          @Override
          public void add(String name) {
      
          }
      
          @Override
          public void delete(String name) {
      
          }
      
          @Override
          public void update(String name) {
      
          }
      
          @Override
          public void query(String name) {
      
          }
      
          @Override
          public void time() {
      
          }
      }
      
      package com.OOP.Demo11;
      
      //abstract: 抽象类 : 本质是类  extends  :单继承    (接口可以多继承)
      public abstract class Action {
          //约束-有人帮我们实现
          //abstract  , 抽象方法,只有方法名字,没有方法的实现!
          public abstract void doSomething();
          /*
          特点:
          1.不能使用new这个抽象类,只能靠子类去实现它:约束
          2.抽象类中可以写普通方法,只能靠子类去实现它:约束
          3.抽象方法必须在抽象类中,只能靠子类去实现它:约束
          抽象的抽象:约束
          4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
           */
      
      }
      
  7. 内部类及OOP实战

    • 内部类(奇葩的东西)

      • 内部类就是在一个类的内部定义一个类,比如,A中定义一个B类,那么B类相对A类来说就成为内部类,而A类相对B类来说就是外部类了

        1. 成员内部类

        2. 静态内部类

        3. 局部内部类

        4. 匿名内部类

          package com.OOP.Demo13;
          
          public class Outer {
              private  int id=10;//私有的
              public  void out(){
                  System.out.println("这是外部类的方法");
              }
              //局部内部类
              public void  method(){
                  class Inner{
                      public void in(){
                          System.out.println("这是局部内部类的方法");
                      }
                  }
              }
              /////////////////////////////////
              public
              class Inner{
                  public void in(){
                      System.out.println("这是内部类的方法");
                  }
                  //获得外部类的私有属性
                  public void getIn(){
                      System.out.println(id);
                  }
                  public void getout(){
                     out();
                  }
              }
          
          }
          //一个Java类中可以有多可个,class类,但是只能有一个 public  class
          class A{
          
          
                  }
          
          package com.OOP.Demo13;
          
          public class Test {
              public static void main(String[] args) {
              /*
                  //外部类通过 new写法
                  Outer outer =new Outer();
                  //通过外部类来实例化内部类
                  Outer.Inner inner=outer.new Inner();
                  inner.in();
                  inner.getIn();
                  inner.getout();
               */
              //没有名字 初始类,不用将实例保存到变量
                  new Apple().eat();
          
                  //匿名内部类(java高阶)
                  new UserService(){
          
                      @Override
                      public void eat() {
          
                      }
                  };
              }
          }
          class  Apple{
              public void eat(){
                  System.out.println("1");
              }
          
          }
          interface UserService{
          
              void eat();
          }
          
  8. 异常机制(Exception)

    1. 什么是异常

      • 软件运行过程中,非常可能遇到异常问题,我们叫异常,英文:Exception,这些异常情况,让我们写的程序做出合理的处理而不至于程序崩溃
      • 异常指程序运行中出现的不期而至的各种状况,如文件找不到,网络连接失败,非法参数等等
      • 异常发生在程序运行期间,它影响了正常的程序执行流程

      简单分类:

        	1. 检查性异常:最具代表的检查性异常时用户错误或问题引起的异常,这是程序员无法预见的(例如:打开一个不存在的文件时,体格一场就发生了,这些异常在编译是不能被简单地忽略掉)
        	2. 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时一场可以在编译时被忽略。
        	3. 错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如当栈溢出时,一个错误就发生了,他们在编译也检查不到
      
    2. 异常体系结构(异常框架)

      1. Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类

      2. 在Java ApI 中已经定义了很多异常,这些异常主要分为两类,错误ERROR和异常Exception

        img

      Error:(和程序员无关)

      • Error类对象由java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关

      • java虚拟机运行错误(Virtual Machine Error),当JVM不在有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时Java虚拟机(jvm)一般会选择线程终止;

      • 还有发生在虚拟机试图执行应用时,如类定义错误(NoclassDefFoundError),链接错误(LinkageError)这些错误时不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数时程序运行时不允许出现的状况

      Exception:(和程序员有关)

      • 在Exception分支中有一个重要的子类RuntimeException(运行时异常)

        • ArrayIndexOutOfBoundsException(数组下标越界)
        • NullPointerException(空指针异常)
        • ArithmeticException(算术异常)
        • MissResourceException(丢失资源)
        • ClassNotoundException(找不到类)
        • 等等这些异常是不检查异常,程序中可以选则捕获处理,也可以不处理
      • 这些异常一般是有程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常发生。

      • Exception和Error的区别:

        ​ Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会终止线程;

        ​ Exception:通常情况下是可以被当作程序处理的,并且在程序中应该尽可能的去处理这些异常。

    3. Java异常处理机制和处理异常

      • 抛出异常

      • 捕获异常

      • 异常处理的五个关键字:

        1. try:尝试处理什么东西

        2. catch:捕获

        3. finally:异常的善后

        4. throw:在方法中使用

        5. throws:方法上抛出异常使用 throws

          package com.exception;
          
          public class Demo1 {
              public static void main(String[] args) {
          
                  new Demo1().test(1,0);
              }
              //假设这个方法中,处理不了这个异常,方法上抛出异常使用  throws
              public void test(int a ,int b) throws ArithmeticException{
                  if (b==0){//主动抛出异常  throw
          
                      throw new ArithmeticException();//主动抛出异常,一般在方法中使用
                  }
              }
          }
          /*
             int a=1;
                  int b=0;
                  //从上到下:依次为从下到大,不然就会捕获失败
                  try {//try监控区域
                      if (b==0){//主动抛出异常  throw
          
                          throw new ArithmeticException();//主动抛出异常
                      }
                      System.out.println(a/b);
                  }catch (ArithmeticException e){         //catch(想要捕获的异常类型): 捕获异常
                      System.out.println("程序出现异常,变量b不能为0");
                  }catch (Throwable throwable){         //catch(想要捕获的异常类型): 捕获异常
                      System.out.println("程序出现异常");
                  }
                  finally {                              //finally 处理善后工作
                      System.out.println("finally");
                  }
          
                  //finally 可以不要finally,假如IO流就需要,在最后使用进行资源关闭
          
           */
          
          package com.exception;
          
          public class Demo2 {
          
              public static void main(String[] args) {
                  //先选中   Ctrl +  Alt + T  自动生成异常
                  int a=1;
                  int b=0;
          
                  try {
                      System.out.println(a/b);
                  } catch (Exception e) {
                      System.exit(1);
                      e.printStackTrace();//打印错误的栈信息
                  } finally {
                  }
              }
          
          }
          
    4. 自定义异常:

      ​ 使用Java内置的异常类可以描述在编程时出现的大部分情况。除此之外,用户还可以自定义异常。用户自定义异常,只需要继承Exception类即可。

      在程序中自定义异常类,大致类分为以下几个步骤;

        		1. 创建自定义异常类
        		2. 在方法中通过throws关键字抛出异常对象
        		3. 如果在抛出异常的方法中处理异常,可以使用try--catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续下一步操作
        		4. 在出现异常方法的调用者中捕获并处理异常。
      

      总结:

      实际应用中的经验总结:

      Alt+Enter:快捷键处理红线

      1. 处理运行异常时,可以采用逻辑去合理规避同时辅助try--catch处理

      2. 再多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常

      3. 对于不确定的代码,也可以加上一个try--catch,来处理潜在的异常

      4. 尽量去处理异常,切记只是简单的调用 printStackTrace()去打印输出

      5. 具体如何处理异常,要根据不同的业务需求和异常类型去决定

      6. 经理添加finally语句块去释放占用的资源

        package com.exception;
        
        //自定义异常
        public class myException extends Exception {
        
            //传递数字>10
            private int detail;
        
            public myException(int detail) {
                this.detail = detail;
            }
            //toString():异常的打印信息
            @Override
            public String toString() {
                return "myException{" + detail + '}';
            }
        }
        
        package com.exception;
        
        public class test {
            //可能会存在异常的方法
            static void test(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{
                    test(1);
                }catch (myException e){
                    System.out.println("myException>="+e);
                }
            }
        }
        

每个人都是在努力的路上,别因为别人的误解而放弃,,术业有专攻,如是而已。
原文地址:https://www.cnblogs.com/16699qq/p/12565539.html