• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
acmer4302
博客园    首页    新随笔    联系   管理    订阅  订阅
面向对象三大特性:封装,继承,多态

面向对象三大特性+内部类+异常类


封装

  • 该露的露,该藏的藏

    • 我们程序设计要追求“高内聚,低耦合”。高内聚:类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
  • 封装(数据的隐藏)

    • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
  • 记住这句话就够了:属性私有:get/set


继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

  • extends的意思是“扩展”。子类是父类的扩展。

  • Java中类只有单继承,没有多继承!

  • 关系 学生是人,学生继承人 学生类是子类/派生类

  • 继承是类与类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合,聚合等

  • public protected default private
    一般来讲  只有属性才会是private
    ctrl + H :显示继承关系
    
  • Java中所有的类 都默认直接或者间接继承Object

  • super关键字:父类

    • 和this相对
    • 但父类私有的东西无法被继承
    • image-20201210194641843
    • 注意点:
      • 1.super调用父类的构造方法,必须在构造方法的第一个
      • 2.super必须只能出现在子类的方法或者构造方法中
      • 3.super和this不能同时调用构造方法
      • this()本类构造 super()调用父类构造
  • 子类默认调用父类无参构造

  • 方法重写:重点 ------>多态

    • 重写是方法的重写,和属性无关

    • //静态方法和非静态的方法区别很大
      //静态方法的调用只和左边,定义的数据类型有关
      //重写只能是非静态方法  IDEA会有个相应的标
      A a=new A();
      a.test();//A
      //父类的引用指向了子类
      B b=new A();
      b.test();//B
      
    • 重写:需要有继承关系,子类重写父类的方法

      • 1.方法名必须相同
      • 2.参数列表必须相同
      • 3.修饰符:范围可以扩大 public>protected>default>private
      • 4.抛出异常:范围可以被缩小,但不能被扩大;ClassNotFoundException-->Exception(大)
    • 为什么需要重写

      • 父类实现的功能子类不一定需要或者不一定满足
    • 快捷键:Alt+Insert 选中override


多态

  • 即同一方法可以根据发送对象的不同而采用多种不同的动作

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

    • new Student();
      new Person();
      
    • //可以指向的引用类型就不确定了,父类的引用指向子类
      //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
      
      //Student能调用的方法都是自己的或者继承父类的
      Student s1=new Student();
      //Person父类型 可以指向子类,但是不可以调用子类独有的方法
      Person s2=new Student();
      Object s3=new Student();
      //对象能执行哪些方法 主要看对象左边的类型 和右边关系不大
      s2.eat();//子类重写了父类的方法,执行了子类的方法
      s1.eat();
      
      总结:根据左边类型进行调用 但是如果子类重写了 会调用子类的
      
  • 多态注意事项:

    • 1.多态是方法的多态,属性没有多态
    • 2.父类和子类,必须有联系,否则类型转换异常!ClassCastException!
    • 3.存在条件:继承关系+方法需要重写+父类的引用指向子类对象!
      • Father f1=new Son();
    • 注意:
      • 1.static 方法:属于类,它不属于实例 不能被重写
      • 2.final 常量:不再被重写
      • 3.private 方法:私有的不能被重写
  • instanceof (类型转换)引用类型

    • X instanceof Y
      • 编译能不能通过 取决于X与Y是否存在父子关系
      • 最后结果对错 取决于X指向的实际类型是不是Y的子类型

    image-20201210211350110

  • 类型之间的转换

    • 基本数据类型 低转高 强制转换

    • 引用类型

      • Person person=new Student()
        //student将这个对象转换为Student类型 我们就可以使用Student类型的方法了 
        Student student=(Student)person;
        student.go();
        Student student=new Student();
        student.go();
        Person person =student;//隐式低转高
        ~~person.go()~~//数据(方法)丢失
        
      • 父类引用指向子类的对象

      • 把子类转换为父类,向上转型

      • 把父类转换为子类,向下转型,强制转换

      • 方便方法的调用,减少重复的代码!简洁


static总结

  • class Student{
    	private static int age;//静态变量
        private double score;//非静态变量
        //总结:静态方法不能调用非静态方法
        public void run(){
            go();//非静态
        }
        public static void go(){
            ~~run()~~;//非法
        }
        main(String[] args){
            Student s1=new Student();
            s1.age
            s1.score
            Student.age
            go();
            Student.go();
        }
    }
    class Person{
        {
            //代码块(匿名代码块)
        }
        static{
            //静态代码块  和类一块执行  永久只执行一次
        }
        public Person(){
            sout("构造方法")
        }
    }
    //骚东西---静态导入包
    import static java.lang.Math.random;
    
    main(){
        random();
    }
    //final之后断子绝孙
    

抽象类

  • public abstract class Action{
        //约束~有人帮我们实现
        //abstract 抽象方法,只有方法名字 没有方法的实现!
        //继承Action  必须实现
        public abstract void doSomething();
    }
    //抽象类的所有方法,继承了它的那些子类,都必须要实现它的方法~ 除非子类也是抽象类
    public class A extends Action{
    	//override
        public void doSomething(){
      		      
        }
    }
    java类单继承 但是java的接口可以实现多继承
    
  • 特点:

    • 不能new这个抽象类,只能靠子类去实现它 :约束!
    • 抽象类里面可以写普通方法
    • 抽象方法必须在抽象类中
    • 抽象类存在构造器吗
    • 存在的意义: 抽象出来 提高开发效率

接口

  • 普通类:只有具体实现

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

  • 接口:只有规范!自己无法写方法~专业的约束! 约束和实现分离:

    • 公司:面向接口编程~
  • 面向对象的精髓,是对对象的抽象,最能体现抽象的就是接口

  • //抽象的思维~Java   架构师需要具备的
    public interface UsrService{
        //接口里面的属性都是常量
        //类型默认为public static final
        int age;
    	//接口中的所有定义其实都是抽象的  public abstract
        void add(String name);
        void delte(String name);
    }
    //每个接口对应一个实现类
    //类可以实现接口  implements 接口
    //实现了接口的类,就需要重写接口中的方法~
    public interface TimeService{
        void timer();
    }
    public class UserService implements UsrService{
        
    }
    
  • 作用

    • 1.约束
    • 2.定义一些方法,让不同的人实现
    • 3.public abstract
    • 4.public static final 属性类型
    • 5.接口不能被实例化,接口中没有构造方法
    • 6.implements可以实现多个接口
    • 7.必须要重写接口中的方法
    • 8.总结博客~

内部类

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

    class Outer{
        private int id;
        public void out(){
            sout("这是外部类的方法")
        }
        class Inner{
            public in(){
                sout("这是内部类的方法")
            }
            //可以获得外部类的私有属性 私有方法
            public void getID(){
                sout(id);
            }
        }
    }
    class Application{
        main(){
            Outer outer = new Outer();
            Outer.Inner inner = outer.new Inner();
            inner.getID();
        }
    }
    
  2. 静态内部类

    class Outer{
        private int id;
        public void out(){
            sout("这是外部类的方法")
        }
        static class Inner{
            public in(){
                sout("这是内部类的方法")
            }
            //可以获得外部类的私有属性 私有方法
            public void getID(){
                sout(id);
            }
        }
    }
    class Application{
        main(){
            Outer outer = new Outer();
            Outer.Inner inner = outer.new Inner();
            inner.getID();
        }
    }
    
  3. 局部内部类

    public class Outer{
        public void meethod(){
            class Inner{
                public void in(){
                    
                }
            }
        }
    }
    //一个java类中可以有多个class类 但是只能有一个public class
    class A{
        public static void main()
    }
    
  4. 匿名内部类

    public class Test{
        main(){
            //没有名字初始化类,不用将实例保存到变量中
            new Apple().eat();
            UsrService usrservice = new UsrService(){
                public void hello(){
                    
                }
            };
        }
    }
    //一个java类中可以有多个class类 但是只能有一个public class
    class Apple{
        public void eat(){
            sout("1");
        }
    }
    interface UsrService{
        void hello();
    }
    

异常机制

  • 什么是异常

  • 简单分类

    • 检查性异常

      • 用户错误或者问题引起的异常,这是程序员无法预见的
    • 运行时异常

      • 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略
    • 错误

      • 错误不是异常,而是脱离程序员控制的问题,例如:栈溢出
  • Java设置了异常体系结构

    • Java把异常当作对象来处理,并定义了一个基类java.lang.Throwable作为所有异常的超类
    • 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception
  • Error

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

image-20201215105742944


异常处理机制

  • Test{
        main(){
            int a=1;
            int b=0;
            //假设要捕获多个异常:从小到大
            try{//try监控区域
                if (b==0){//主动的抛出异常  throw 
                    throw new ArthriticEcception();//一般在方法中使用
                }
                sout(a/b);
            }catch(Throwable e){//想要捕获的异常类型  catch 捕获异常
                sout("程序出现异常,变量b不能为0");
            }catch(){//把最大的抛出写在后面
                
            }finally{//处理善后工作
                sout("finally");//都会被执行
            }
        }
    }
    
    //假设这方法中,处理不了这个异常,方法上抛出异常
    public void test(int a,int b) throws ArithmeticException{
        if(b==0){//throw throws
            throw new ArithmeticException();//主动的抛出异常,一般在方法中使用
        }
    }
    
  • 快捷键

    • 选中 然后ctrl + alt +t
  • 异常关键字

    • try catch finally throw throws

自定义异常

  • 继承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+'}';
        }
    }
    public class Test{
    	static void test(int a){
            sout("传递的参数为1")
            if(a>10){
                trow new MyException(a);//有错误
                //两种方式处理异常
                //try catch 或者 throw new MyException(a);//抛出
            }
            sout("OK");
        }
        public static void main(String[] args){
            try{
                test(1);
            }catch(MyException e){
                sout("MyException=>"+e);
            }
        }
    }
    
  • 经验总结

    • 处理运行时异常时,采用逻辑去合理规避同时辅助try catch处理
    • 在多重catch块后面,可以加上一个catch(Exception)来处理可能会被遗漏的异常
    • 对于不确定的代码,也可以加上try catch,处理潜在的异常
    • 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
    • 具体如何处理异常,要根据不同的业务需求和异常类型去决定
    • 尽量添加finally语句块去释放占用的资源
    • alt + enter
posted on 2020-12-10 21:32  wjs_ouc  阅读(140)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3