Java面向对象编程

本文讲述了面向对象编程的核心概念,如面向过程与面向对象的对比,封装、继承和多态的实现,以及Java中的类、对象、构造器、方法重写、异常处理和内部类。通过实例解析展示了如何在实际项目中应用这些技术。
摘要由CSDN通过智能技术生成

面向对象

  1. 面向过程&面向对象
    • 面向过程:步骤清晰简单,第一步做什么,第二部做什么。。。
    • 面向对象:分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索,面向对象适合处理复杂问题,适合处理需要多人协作的问题。
    • 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整合系统。但是具体到微观操作,仍然需要面向过程的思路去处理。
  2. 面向对象编程(Object-Oriented Programming,OOP
  3. 本质:以类的方式组织代码,以对象的形式组织(封装)数据
  4. 核心思想:抽象
  5. 三大特性:
    • 封装
    • 继承
    • 多态

方法回顾和加深

  1. 方法的定义
    • return 结束方法,返回一个结果
    • 修饰符
    • 参数列表(参数类型,参数名)…
    • 异常抛出:后面讲解
  2. 方法的调用:递归
    • 静态方法:static关键字,有这个关键字的方法和类一起加载,而没有这个关键字,当类实例化之后才存在

    • 非静态方法

      public class Demo1 {
      public void say(){
          System.out.println("say what");
      }
      public static void main(String[] args) {
          Demo1 student = new Demo1();
          student.say();
      }
      }
      
    • 形参和实参

      public class Demo2 {
      public static void main(String[] args) {
          int add = Demo2.add(1,2);//实参
          System.out.println(add);
       }
      public static int add(int a,int b){//形参
          return a + b;
       }
      }
      
    • 值传递

      	public class Demo3 {
          public static void main(String[] args) {
              int a = 1;
              System.out.println(a);
              Demo3.change(1);
              System.out.println(a);//1
          }
          public static void change(int a){
              a = 10;
          }
      }
      

      输出:
      值传递输出

    • 引用传递

      	public class Demo4 {
          public static void main(String[] args) {
             Student student = new Student();
             System.out.println(student.name);//null
             Demo4.change(student);
             System.out.println(student.name);//hhh
          }
      
          public static void change(Student student){
              student.name = "hhh";
          }
      }
      class Student{
          String name;
      }
      

      输出:
      引用传递输出

对象的创建分析

  1. 类与对象的关系:类是一种抽象的数据类型,它是对某一类事物整体描述,如动物,手机等,而对象是抽象概念的具体实例,如狗,华为手机等
  2. 创建与初始化对象
    • 使用new关键字创建对象(使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用)
      无参构造必须显示定义,否则会报错,如下图所示:
      有参构造
      无参构造必须显示定义,如下图所示:
      无参构造
      生成有参构造器快捷键:ALT + insert键
      生成无参构造器快捷键:ALT + insert键 选择无参即可
      使用new关键字,本质是在调用构造方法,初始化对象的值
      构造器:和类名相同 没有返回值 是public型
      注意:定义有参构造之后,如果想用无参构造,需要显示的定义一个无参的构造

      内存分析:图来自狂神说Java
      new关键字的内存分析

面向对象三大特性

  1. 封装
    • 高内聚,低耦合 高内聚:类的内部数据操作细节自己完成;低耦合:仅暴露少量的方法给外部使用
    • 提高程序的安全性,保护数据
    • 隐藏代码的实现细节
    • 统一接口
    • 增加系统可维护性
    • 本质:属性私有,get/set方法访问属性
          public class Demo6 {
            public static void main(String[] args) {
                Student_new student_new = new Student_new();
                student_new.setName("hhhh");
                student_new.getName();
            }
        }
        
        class Student_new{
            private String name;
            private int id;
            private char sex;
        
            //提供一些可以操作这个属性的方法
            //get
            public String getName(){
                return this.name;
            }
            public void setName(String name){
                this.name = name;
            }
        }
      
  2. 继承
    • 本质:对某一批类的抽象 关键字 extends,子类是父类的扩展
    • Java中类只有单继承,没有多继承
      • 继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖,组合,聚合等
      • 继承关系的两个类,一个为子类,一个为父类 ctrl + H:展示类继承关系
      • 子类和父类之间,从意义上讲,应该具有“is a”的关系,子类继承父类,就会拥有父类的全部方法,Java中,所有类直接或间接继承object类私有内容无法被继承
      • super
        1). 先调用父类的构造器,必须要在子类构造器的第一行
        2). super 必须只能出现在子类的方法或者构造方法中
        3). super和this不能同时调用构造方法
        与this的区别
        1). 代表的对象不同 this:本身调用者这个对象 super:代表父类对象的应用
        2). 前提:this 没有继承也可以使用 super只能在继承条件下才可以使用
        3). 构造方法:this();本类的构造 super():父类的构造
        public class Main {
            public static void main(String[] args) {
                Student student = new Student();
                student.test("hh");
                student.test_1();
            }
        }
        //子类继承父类,就会拥有父类的全部方法
        //Java中,所有类直接或间接继承object类
        //私有内容无法被继承
        class Person{
            protected String name = "hhh";
            public Person() {
                System.out.println("Person 无参构造器执行");
            }
            public void print(){
                System.out.println("Person");
            }
        }
        class Student extends Person{
            //隐藏代码
            //super();
            //先调用父类的构造器,必须要在子类构造器的第一行
            private String name = "h";
            public Student() {
                System.out.println("Student 无参构造器执行");
            }
        
            public void print(){
                System.out.println("student");
            }
            public void test(String name){
                System.out.println(name);
                System.out.println(this.name);
                System.out.println(super.name);
            }
            public void test_1(){
                print();
                this.print();//当前类对象
                super.print();//父类方法
            }
        
        }
        
        输出:
        super
      • 方法重写
        1). 重写:需要继承关系,子类重写父类的方法
        2). 注意:方法名必须相同,参数列表必须相同,修饰符:范围可以扩大但是不能缩小:public > protected >default > private 抛出异常:范围可以被缩小,但是不能扩大:classNotFoundException --> Exception(大)
        3). 为什么需要重写:父类的功能子类不一定需要,或者不一定满足!快捷键“ Alt + Insert 选Override
           public class Demo1 {
               //静态方法和非静态方法有区别
               //非静态方法重写
               public static void main(String[] args) {
                   //静态方法的调用只和左边定义的数据类型有关
                   A a = new A();
                   a.test();
                   //父类的引用指向了子类
                   B b = new A();
                   b.test();
               }
           }
           
           class B{
               public  void test(){
                   System.out.println("B test");
               }
           }
           class A extends B {
               public  void test(){
                   System.out.println("A test");
               }
           }
        
        输出:
        方法重写
  3. 多态
    • 可以实现动态编译,增强可扩展性
    • 注意事项:1)多态是方法的多态,属性没有多态 2)父类和子类,有联系,否则类型转换异常 !ClassCastException 3)多态存在条件:继承关系,需要有方法重写,父类的对象指向子类的对象。
    • 不能有多态的: 1)static 方法,属于类,不属于实例 2)final 常量 3)private方法
         public class Demo1 {
             public static void main(String[] args) {
         
                 //一个对象的实际类型是确定的,如new了一个Student对象,则这个对象是属于Student的
                 new Student();
                 //但是这个对象指向的引用类型不确定:父类的引用指向子类
                 //Student 能调用的方法都是自己的或者继承父类的
                 Student student1 = new Student();
                 //Person 父类型,可以指向子类,但是不能调用子类独有的方法
                 Person student2 = new Student();
                 Object student3 = new Student();
                 student2.run();
                 student1.run();
                 //对象能执行哪些方法,主要看对象左边的类型,
                 student2.eat();
             }
         }
         
         class Person{
             public void run(){
                 System.out.println("run");
             }
         }
         class Student extends Person{
             public void run(){
                 System.out.println("son");
             }
             public void eat(){
                 System.out.println("eat");
             }
         }
      
    • instanceof (类型转换)引用类型 判断一个对象的类型
      1) 注意使用该关键字需要两个之间有关系 X instanceof Y,重点是判断对象类型是根据new关键字确定的
         public class Demo2 {
             public static void main(String[] args) {
                 Object object = new Person1();
                 Person1 person1 = new Student1();
                 Person1 person2 = new Teacher();
         
                 System.out.println(person1 instanceof Teacher);
                 System.out.println(person1 instanceof Person1);
                 System.out.println(person1 instanceof Student1);
         
                 System.out.println();
                 System.out.println(person2 instanceof Teacher);
                 System.out.println(person2 instanceof Person1);
                 System.out.println(person2 instanceof Student1);
             }
         }
         
         class Person1{
         
         }
         class Teacher extends Person1{
         
         }
         class Student1 extends Person1{
         
         }
      
      输出:
      instanceof
      2) 类型转换
      	public class Demo3 {
      	    public static void main(String[] args) {
      	        //高 -----低
      	        A b = new B();
      	        B c = (B) b;
      	        //多态存在条件:父类引用指向子类的对象
      	        //把子类转换为父类,向上转型;
      	        //把父类转换为子类,向下转型,强制转换
      	        //方便方法调用,减少重复代码,核心思想:简洁
      	    }
      	}
      	
      	class A{
      	
      	}
      	class B extends A{
      	
      	}
      

static

  1. 静态代码块,主要赋初值,只加载一次
    	public class Demo4 {
    	    public static void main(String[] args) {
    	        S_test sTest = new S_test();
    	    }
    	}
    	class S_test{
    	    {
    	        System.out.println("匿名代码块");
    	    }
    	    static {
    	        System.out.println("静态代码块");
    	    }
    	
    	    public S_test() {
    	        System.out.println("构造方法");
    	    }
    	}
    
    输出:
    静态代码块
  2. 使用final关键字的类不能被继承
    	//静态导入包
    	import static java.lang.Math.random;
    	import static java.lang.Math.PI;
    	public class Demo5 {
    	    public static void main(String[] args) {
    	        System.out.println(random());
    	        System.out.println(PI);
    	    }
    	}
    	//final关键字的类,不能被继承
    	final class C{
    	
    	}
    	class D extends C{
    	
    	}
    

抽象类和接口

  1. abstract类修饰
  2. 不能new抽象类,只能靠子类去实现它,约束
    抽象方法必须在抽象类中
    抽象类中可以有普通的方法
    抽象类的声明
  3. 接口
    • 普通类:只有具体实现 抽象类: 具体实现和抽象方法都有
    • 接口:只有规范
    • 接口就是规范,定义的是一组规范
    • OO的精髓:是对对象的抽象,最能体现这一点的就是接口
    • 作用:1. 定义一些方法,让不同的人实现 2. 方法都是public abstract ,常量都是public static final 3. 接口不能被实例化,接口中没有构造方法 4.implements可以实现多个接口,但是必须要重写接口
      接口

内部类及OOP实战

  1. 内部类:就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就称为内部类,A类相对于B类来说就是外部类了。
  2. 成员内部类:
    	class Outer{
        private int id = 10;
        public void out(){
            System.out.println("Outer method");
        }
        class Inner{
            public void in(){
                System.out.println("Inner method");
            }
            public void getID(){
                System.out.println(id);
            }
        }
    }
    
  3. 静态内部类:给内部类加static关键字
  4. 局部内部类:
    	class A{
    	    public void method(){
    	        class Inn{
    	            public void hhh(){
    	
    	            }
    	        }
    	    }
    	}
    
  5. 匿名内部类
    匿名内部类
  6. 完整代码
    	public class Demo1 {
    	    public static void main(String[] args) {
    	        Outer outer = new Outer();
    	        //没有名字初始化类,不用将实例保存到变量中
    	        new Outer().out();
    	        //通过外部类来实例化内部类,可以获得外部类的私有属性
    	        Outer.Inner inner = outer.new Inner();
    	        inner.in();
    	        inner.getID();
    	    }
    	
    	}
    	class Outer{
    	    private int id = 10;
    	    public void out(){
    	        System.out.println("Outer method");
    	    }
    	    class Inner{
    	        public void in(){
    	            System.out.println("Inner method");
    	        }
    	        public void getID(){
    	            System.out.println(id);
    	        }
    	    }
    	}
    	class A{
    	    public void method(){
    	        class Inn{
    	            public void hhh(){
    	
    	            }
    	        }
    	    }
    	}
    
    输出:
    输出

异常

  1. 异常定义

    • 程序运行中出现的不期而至的各自状况,如:文件找不到、网络连接失败、非法参数等
    • 检查性异常:用户错误或问题引起的异常,这是程序员无法预见的。eg:要打开一个不存在的文件时,一个异常就发生了,这些异常在编译时不能被简单的忽略。
    • 运行时异常:运行时异常是可能被程序员避免的异常
    • 错误error:错误不是异常,而是脱离程序员控制的问题。错误在代码中常被忽略
  2. 异常体系结构

    • Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类
    • 异常分为两大类:错误error和异常exception
    • Error: Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
      1)Java虚拟机运行错误(Virtual MachineError):当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择终止线程;
      2)还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为他们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的情况。
    • Exception:
      1)RuntimeException:ArrayIndexOutOfBoundsException; NullPointException; ArithmetricException; MissingResourceException; ClassNotFoundException等,这些异常是不检查异常,程序中可以捕获处理,也可以不处理。

    以下图来自狂神
    异常

  3. Java异常处理机制
    抛出异常,捕获异常
    异常处理五个关键字:try catch finally throw throws

    • try catch finally

       public class Demo1 {
           public static void main(String[] args) {
               int a = 1;
               int b = 0;
               //捕获多个异常,从小到大
               try {
                   //监控区域
                   System.out.println(a / b);
               }catch (ArithmeticException e){
                   //捕获异常
                   System.out.println("Exception,b不能等于 0");
               }catch (Error e){
                   //捕获异常
                   System.out.println("Exception 循环调用");
               } finally {
                   //善后,可以不要
                   System.out.println("finally");
               }
           }
           public void a(){
               b();
           }
           public void b(){
               a();
           }
       }
      

      输出:
      try-catch捕获异常

    • 主动抛出异常,throw
      什么也不做
      和上面代码一样,输出:
      主动抛出异常
      或者主动抛出异常 throw

      import outer_Class.Demo1;
      
      public class Demo2 {
          public static void main(String[] args) {
              new Demo2().test(1,0);
          }
          public void test(int a,int b){
              if (b == 0){
                  throw new ArithmeticException();//主动抛出异常,一般在方法中使用
              }
              System.out.println(a / b);
          }
      }
      

      输出:
      主动抛出异常

    • 主动抛出异常,throws

      import outer_Class.Demo1;
      
      public class Demo2 {
          public static void main(String[] args) {
              try {
                  new Demo2().test(1,0);
              }catch (ArithmeticException e){
                  System.out.println("hhh");
      //            e.printStackTrace();
              }
      
      
          }
          public void test(int a,int b) throws ArithmeticException{
              if (b == 0){
                  throw new ArithmeticException();//主动抛出异常,一般在方法中使用
              }
              System.out.println(a / b);
          }
      }
      

      注意:在方法名字那里主动抛出异常,使用throws关键字,要用try-catch捕获
      输出:
      throws捕获异常

  4. 自定义异常

    • 用户定义异常,只需要继承Exception类即可
    • 自定义异常类步骤:1)创建自定义类;2)在方法中通过throw关键字抛出异常;3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步的操作;4)在出现异常方法的调用者中捕获并处理异常。
      public class Demo3 {
          public static void main(String[] args) {
              try {
                  Demo3.test(1);
              }catch (MyException e){
                  System.out.println("My Exception :" + e);
              }
          }
          static void test(int a) throws MyException{
              System.out.println("传递的参数为:" + a);
              if (a > 10){
                  throw new MyException(a);
              }
              System.out.println("OK");
          }
      }
      class MyException extends Exception{
          private int detail;
          public MyException(int a) {
              this.detail = a;
          }
      
          @Override
          public String toString() {
              return "MyException{" + "detail=" + detail + '}';
          }
      }
      
      输出:
      自定义异常类_合法输入
      当传递参数为10时,则抛出异常:
      在这里插入图片描述
  5. 总结

    • 处理运行时异常时,采用逻辑去合理规避同时辅助使用try-catch处理
    • 在多重catch块后面,可以加一个catch(Exception)来处理可能被遗漏的异常
    • 对于不确定的代码,也可以加上try-catch,处理潜在的异常
    • 尽量去处理异常,切忌只是简单调用printStackTrace()去打印输出
    • 尽量添加finally语句块去释放占用的资源
    • 快捷键:Alter+ ctrl键
  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值