• Java第八课


    Java第八课

    一、super

    • super的意思是超级的,主要是和父类有关

    • 用法

      1. 调用父类的构造方法

        如果父类有默认构造方法,则可以不用super,但是,如果父类只有有参构造方法,此时,在创建子类对象时,在子类的构造方法中就要显示的调用super构造方法

        class Father{}
        Son son = new Son()
        执行new Son()时先执行new Father();
        以上代码是默认构造方法,JVM可以自动调用,用不上super
        真实运行时这样的:
        class Son extends Father{
        public Son(){
        super();
        }
        }

        -- 以上是默认的构造方法,如果父类没有默认构造方法,就要显示调用,此时使用super。

        public class Father {
           public Father(String name) {
               System.out.println("father" + name);
          }
        }
        class Son extends Father{

           public Son(String name) {
               super(name);
          }
        }

        -- 如果父类的构造方法不是默认的,子类必须要有和它匹配的构造方法,重点是:在子类中使用super调用父类的构造方法,并且传入参数。

        -- super在子类构造方法中必须是第一行代码。

      2. 用super调用子类覆盖的父类的方法

        比如:父类有say(),子类也有say(),并且say被覆盖,如果在子类中想要调用父类的say方法,只能使用super.say();

        public class Father {
           public Father(String name) {
               System.out.println("father" + name);
          }

           public void say() {
               System.out.println("father say");
          }

           /**
            * 调用this,此时this是谁,多态的知识点,不管this代码在哪里,关键是看声明,
            * Father son = new Son(),指向的是son的say
            * Father father = new Father(),指向的是father的say
            *
            */
           public void fatherTest() {
               this.say();
          }
        }
        class Son extends Father{

           public Son(String name) {
               super(name);
          }

           @Override
           public void say() {
               System.out.println("son say");
          }

           public void test() {
               say();
               super.say();// 用super调用被重写的父类的方法
          }

           public static void main(String[] args) {
        /*       Son son = new Son("son");
               son.test();*/
               Father son = new Son("son");
               // son.test();
               // 在编译器看来,此时的son的身份是father,son中具有father的成员,没有子类的成员
               son.fatherTest();
          }
        }
    • 多态:this.say(),关键是看声明的时候创建的是谁的实例,

    二、instanceof和强转

    instanceof运算符是特殊的运算符,可以判断某个对象是否某个类的实例。 如果B是A的子类,则: A obj = new B(); 赋值号= 左边是大类型,基本类型,右边是子类型,则可以自然转换,如:Chinese obj = new Shanxi(); if (obj instanceof B) 则B b = (B)obj;当检查到obj实际身份是B时,可以还原其身份到B类型,但此时obj的外在身份依然是A,所以转换时还是要加括号进行强转,强转的前提是类型正确,比如C也是A的子类,上面的obj就不能强转成C,会报类型转换错误的异常。

    三、接口

    • interface 类的行为规范

    • 类有什么用?实现某些业务,存储数据,传递数据(方法的参数)

      POJO,Java原始类,这样的类用来存储数据和传递数据,bean包,entify包(类似于这些放简单类的包)下都是POJO

      1. JDK8之前,接口中只有抽象方法和常量,接口中的所有的方法默认都是抽象的,所以在定义方法时不用写public和abstract。

        void say();//等价于public abstract void say();

        接口中的变量都是常量,因为变量会默认加上public static final,

        int UPDATE_SUCCESS = 1;// 等价于 public static final

        常量的命名要大写,单词和单词之间用“_”隔开

      2. JDK8开始,接口中有了默认方法,这些方法有方法体,方法用关键字default定义,接口不用来实现业务,只定义行为要求,需要做什么,具体实现细节由接口的实现类来完成。如果一个接口中有N个方法,实现类就要实现N个方法,如果没有实现所有的方法,则该类是抽象类。

        在JDK原码中,有大量的实现接口没有完全实现的抽象类,他们可以分层次的去实现.

        有的项目组接口的定义规则是以"I"开头,实现类以”impl“结束

        implement实现,impl是缩写

        java中的继承是单继承的,只能有一个父类,java中可以同时实现多个接口。

        public class Son extends Father implement IAnimal,IDao{

        }

        接口时不能创建实例的,接口可以使用多态的技术,具有父类的效果。接口中的方法是抽象的,抽象类中的方法是对接口中的方法的重写,这也体现出父类和子类的特点。

    • 接口特点

      1. 不能创建实例

      2. 只能定义常量

      3. 普通方法都为抽象方法

      4. default方法可以有方法体

      5. 类可以同时实现多个接口

    • 抽象类特点

      1. 抽象类不能创建实例

      2. 可以定义抽象方法和普通方法

      3. 单继承

    • 接口1和接口2中的方法相同,实现一个另外一个自动实现

    • 当接口1和接口2中有相同的方法,但是返回值不兼容,实现类无法实现这两个类。

    • 如果接口1和接口2的返回值兼容,即使不一样,实现类也可以同时实现两个方法。

    结论:Java中的单继承是指类的单继承,接口可以多继承

    接口继承多个接口时,多个接口中不能有冲突的方法存在

    当一个类同时实现一个接口和继承一个父类时,父类和接口中的方法也不能冲突。

    四、包

    • 包是用来管理类的,可以避免同名类的冲突,每个包有相应的功能,包下的类就是这相应功能的类。

      通常工程中的类有几大功能:

      控制器类,业务类,数据库类,POJO类

      根据这些功能建对应的包:controller包,service包,dao包,bean包

      不同的包下放同一类功能的类

      包的另一个功能,管理权限。

      修饰符,访问修饰符:private<default(不写)<protected<public

       类内部包内部继承包外(不继承)
      public OK OK OK OK
      protected OK OK OK NO
      default(不写) OK OK NO NO
      private OK NO NO NO

      包内:包里有A,B两个类,A中的public,protected,default成员都可以在B中访问,A中的private不可以

      继承:包1中有A,包2中有B,B类继承A类,B类只能访问A类中的public和protected,default和private不能访问,default只能在同一个包下互相访问,出了包不可以,protected因为继承的关系,在不同的包下可以访问。

      -- 如果父类和子类分别在不同的包下,父类中的default修饰的成员无法在子类中访问,但是protected可以访问

    五、内部类

    包1下定义一个类,该类不是public,是默认的,包2无法访问。

    内部类:定义在一个类内部的类。它可以定义在一个类中的属性的区域或方法中,或一个代码块中,if,for

    内部类可以有名字,可以没有名字(匿名内部类),匿名内部类多用于抽象类或接口的实例化(抽象类和接口本身是不能创建实例的,但是可以通过匿名内部类简介实现)

    内部类的优点:它可以具有类的功能,但是只限于当前类使用,不对外,否则就定义成一个外部的类,可以组织代码,使得代码结构清晰。内部类可以绕开Java的单继承,如果外部类继承了一个类,而此时还想继承另一个类,就让内部类来继承它。

    两点:第一点:别人不用,自己用;第二点:内部类可以定义成为方法来使用,但是方法有局限性,当一个方法完成不了时,需要定义成一个类,方法升级为内部类后,功能增强。

    内部类可以访问外部类的数据(注意静态的使用,如果内部类是静态的,则情况复杂),静态内部类只能访问外部类的静态数据

    分类:

    1. 成员内部类

      • 成员内部类

      • 静态成员内部类

      public class Outer {
         int id = 1;
         /**
          * 成员内部类
          */
         class Inner1{
             public void say() {
                 System.out.println("Inner1 say");
            }
        }

         /**
          * 静态成员内部类
          */
         static class Inner2{
             public void say() {
                 System.out.println("Inner2 say");
            }
        }
         public static void main(String[] args) {
             Outer outer = new Outer();
             // 访问类的成员
             System.out.println(outer.id);
             Outer.Inner1 inner1 = new Outer().new Inner1();
      //       inner1.say();
             Outer.Inner2 inner2 = new Outer.Inner2();
             inner2.say();
        }
      }
    2. 方法内部类

          public void work() {
             /**
              * 方法内部类只能在方法内部使用
              */
             class Inner1{
                 public Inner1(){
                     System.out.println("method Inner1 created");
                }
                 void work() {
                     System.out.println("method Inner1 work");
                }
            }
             Inner1 inner1 = new Inner1();
             inner1.work();
        }
    3. 块内部类

        public void work2() {
           if (id > 0) {
               /**
                * 块内部类
                */
               class Inner1{
                   public Inner1() {
                       System.out.println("if block Inner1 created");
                  }
              }
               Inner1 inner1 = new Inner1();
          }
      }
    1. 匿名内部类

      public class Worker {
         private int age = 10;

         public void test() {
             AbstractWorker abstractWorker = new AbstractWorker() {
                 int id;
                 @Override
                 public void work(String name) {
                     System.out.println("编号:" + id + age + "岁的" + name + "在工作");
                }
            };
             abstractWorker.work("Tom");
        }

         public static void main(String[] args) {
             Worker worker = new Worker();
             worker.test();
        }
      }
      abstract class AbstractWorker{
         /**
          * 工作
          * @param name 工人姓名
          */
         public abstract void work(String name);
      }



    软件下载提取码:qwer
  • 相关阅读:
    对mysql 数据库操作 使其支持插入中文(针对python)
    网页制作中的超链接怎么做
    python requests的安装与简单运用(转)
    ubuntu 修改权限
    [Linux]常用命令与目录全拼
    Python web 简单服务器的搭建与运行
    ubuntu 下终端关于调试C++的命令
    正则表达式基本语法详解
    Linux下 编译C++/C以及常用的几种命令(ubuntu)
    Visual Studio 2013 中 mysql 使用 EF6
  • 原文地址:https://www.cnblogs.com/ty0910/p/14529519.html
Copyright © 2020-2023  润新知