• 重踏学习Java路上_Day10(形参与返回值,包,修饰符,内部类)


    1:形式参数和返回值的问题(理解)
        (1)形式参数:
             类名:需要该类的对象,总之需要类变量的都是需要其实例化的对象      特别例子://匿名对象用法 new StudentDemo().method(new Student());//
            

       抽象类名:需要该类的子类对象,抽象类本身不能实例化,抽象类有构造方法,但不能用作实例化调用,仅仅用于子类访问父类数据的初始化,继承父类的子类方式有两种(1.抽象类继承抽象类,此时不能实例化,但也不用重写抽象方法;2.具体类继承抽象类,重写抽象方法,使其能进行实例化,使其在堆内存区有一份对象数据,把引用地址赋值给抽象类的引用类型变量完成实例化)
            

        接口名:需要该接口的实现类对象,接口本身不能实例化,因为没有构造方法,实现接口的子类方式有两种(1.抽象类实现接口,此时不能实例化,但也不用重写抽象方法;2.具体类实现对象,重写接口抽象方法,使其能进行实例化,使其在堆内存区有一份对象数据,把引用地址赋值给接口的引用类型变量完成实例化)

    例子:

    类作为形式参数:

    class Student {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }

    class StudentDemo {
        public void method(Student s) { //ss; ss = new Student();  Student s = new Student();
            s.study();
        }
    }

    class StudentTest {
        public static void main(String[] args) {
            //需求:我要测试Student类的study()方法
            Student s = new Student();
            s.study();
            System.out.println("----------------");
            
            //需求2:我要测试StudentDemo类中的method()方法
            StudentDemo sd = new StudentDemo();
            Student ss = new Student();
            sd.method(ss);
            System.out.println("----------------");
            
            //匿名对象用法
            new StudentDemo().method(new Student());
        }
    }

    抽象类作为形式参数:

    abstract class Person {
        public abstract void study();
    }

    class PersonDemo {
        public void method(Person p) {//p; p = new Student();  Person p = new Student(); //多态
            p.study();
        }
    }

    //定义一个具体的学生类
    class Student extends Person {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }

    class PersonTest {
        public static void main(String[] args) {
            //目前是没有办法的使用的
            //因为抽象类没有对应的具体类
            //那么,我们就应该先定义一个具体类
            //需求:我要使用PersonDemo类中的method()方法
            PersonDemo pd = new PersonDemo();
            Person p = new Student();
            pd.method(p);
        }
    }

    接口作为形式参数:

    interface Love {
        public abstract void love();
    }

    class LoveDemo {
        public void method(Love l) { //l; l = new Teacher();  Love l = new Teacher(); 多态
            l.love();
        }
    }

    //定义具体类实现接口
    class Teacher implements Love {
        public void love() {
            System.out.println("老师爱学生,爱Java,爱林青霞");
        }
    }

    class TeacherTest {
        public static void main(String[] args) {
            //需求:我要测试LoveDemo类中的love()方法
            LoveDemo ld = new LoveDemo();
            Love l = new Teacher();
            ld.method(l);
        }
    }


        (2)返回值类型:
            类名:返回的是该类的对象
            抽象类名:返回的是该类的子类对象
            接口名:返回的是该接口的实现类的对象

    类,抽象类,接口作为返回值的例子:

    类做返回:

    class Student {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }

    class StudentDemo {
        public Student getStudent() {
            //Student s = new Student();
            //Student ss = s;
            
            //Student s = new Student();
            //return s;
            return new Student();
        }
    }

    class StudentTest2 {
        public static void main(String[] args) {
            //需求:我要使用Student类中的study()方法
            //但是,这一次我的要求是,不要直接创建Student的对象
            //让你使用StudentDemo帮你创建对象
            StudentDemo sd = new StudentDemo();
            Student s = sd.getStudent(); //new Student(); Student s = new Student();
            s.study();
        }
    }

    抽象类做返回:

    abstract class Person {
        public abstract void study();
    }

    class PersonDemo {
        public Person getPerson() {
            //Person p = new Student();
            //return p;
            
            return new Student();
        }
    }

    class Student extends Person {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }

    class PersonTest2 {
        public static void main(String[] args) {
            //需求:我要测试Person类中的study()方法
            PersonDemo pd = new PersonDemo();
            Person p = pd.getPerson(); //new Student();  Person p = new Student(); 多态
            p.study();
        }
    }

    接口做返回:

    interface Love {
        public abstract void love();
    }

    class LoveDemo {
        public Love getLove() {
            //Love l = new Teacher();
            //return l;
            
            return new Teacher();
        }
    }

    //定义具体类实现接口
    class Teacher implements Love {
        public void love() {
            System.out.println("老师爱学生,爱Java,爱林青霞");
        }
    }

    class TeacherTest2 {
        public static void main(String[] args) {
            //如何测试呢?
            LoveDemo ld = new LoveDemo();
            Love l = ld.getLove(); //new Teacher(); Love l = new Teacher(); 多态
            l.love();
        }
    }


        (3)链式编程
            对象.方法1().方法2().......方法n();
            
            这种用法:其实在方法1()调用完毕后,应该一个对象;
                      方法2()调用完毕后,应该返回一个对象。
                      方法n()调用完毕后,可能是对象,也可以不是对象。

    例子:

    /*
        链式编程。
            每次调用完毕方法后,返回的是一个对象。
    */
    class Student {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }

    class StudentDemo {
        public Student getStudent() {
            return new Student();
        }
    }

    class StudentTest3 {
        public static void main(String[] args) {
            //如何调用的呢?
            StudentDemo sd = new StudentDemo();
            //Student s = sd.getStudent();
            //s.study();
            
            //大家注意了
            sd.getStudent().study();
        }
    }

    2:包(理解)
        (1)其实就是文件夹
        (2)作用:
            A:区分同名的类
            B:对类进行分类管理
                a:按照功能分 (CRUD四个功能,四个包,各自底下有学生添加,学生删除老师添加,老师删除等)
                b:按照模块分(老师包,学生包,每个包各自含自己的CRUD功能)
        (3)包的定义(掌握)
            package 包名;
            多级包用"."分开即可。
        (4)注意事项:(掌握)
            A:package语句必须在文件中的第一条有效语句
            B:在一个java文件中,只能有一个package
            C:如果没有package,默认就是无包名
        (5)带包的编译和运行
            A:手动式

                 a.编写一个带包的java文件

                 b.通过javac命令编译该java文件

                 c.手动创建包名

                 d.把b步骤的class文件放到C步骤的最底层包

                 e:回到和包根目录在同一目录的地方,然后运行,记住带包运行。java cn.itcast.HelloWorld
            B:自动式(掌握)
                javac -d . HelloWorld.java (-d:创建目录,"."表示在本路径下创建)

                1.编写一个带包的java文件

                2.javac编译的时候带上-d即可

                        javac -d . HelloWorld.java
                3.回到和包根目录在同一目录的地方,然后运行,记住带包运行java cn.itcast.HelloWorld

              

                不同包下类之间的访问:先编译引入包的java文件,再编译执行包下的java文件,再带包运行

              
    3:导包(掌握)
        (1)我们多次使用一个带包的类,非常的麻烦,这个时候,Java就提供了一个关键字import。
        (2)格式:
            import 包名...类名; //这种方式导入是到类的级别
            另一种:
                import 包名...*;(不建议)
        (3)package,import,class的顺序
            package > import > class

            package:只能有一个

            import:可以有多个

            class:可以有多个,以后建议是一个
        
    4:权限修饰符(掌握)
        (1)权限修饰符
                            本类    同一个包下(包含子类与无关类)    不同包下的子类    不同包下的无关类
            private           Y
            默认               Y            Y
            protected       Y            Y                            Y
            public             Y            Y                            Y                       Y
        (2)这四种权限修饰符在任意时刻只能出现一种
            public class Demo {}        

    5:常见的修饰符(理解)
        (1)分类:
            权限修饰符:private,默认,protected,public
            状态修饰符:static,final
            抽象修饰符:abstract
        (2)常见的类及其组成的修饰
           修饰符:
            权限修饰符:private,默认的,protected,public
            状态修饰符:static,final
            抽象修饰符:abstract
            
        类:
            权限修饰符:默认修饰符,public
            状态修饰符:final
            抽象修饰符:abstract
            
            用的最多的就是:public

           //此处不允许使用修饰符private
      //此处不允许使用修饰符protected
      //此处不允许使用修饰符static

           
        成员变量:
            权限修饰符:private,默认的,protected,public
            状态修饰符:static,final
            
            用的最多的就是:private
            
        构造方法:
            权限修饰符:private,默认的,protected,public
            
            用的最多的就是:public
            
        成员方法:
            权限修饰符:private,默认的,protected,public
            状态修饰符:static,final
            抽象修饰符:abstract
            
            用的最多的就是:public
            
        除此以外的组合规则:
            成员变量:public static final
            成员方法:public static
                      public abstract
                      public final
           
        (3)另外比较常见的:
            public static final int X = 10;
            public static void show() {}
            public final void show() {}
            public abstract void show();

    6:内部类(理解)
        (1)把类定义在另一个类的内部,该类就被称为内部类。
            举例:把类B定义在类A中,类B就被称为内部类。
        (2)内部类的访问规则
            A:可以直接访问外部类的成员,包括私有
            B:外部类要想访问内部类成员,必须创建对象
        (3)内部类的分类 (注意:类与类是平级关系)
            A:成员内部类:在成员位置定义的类,被称为成员内部类
            B:局部内部类:在局部位置定义的类,被称为局部内部类
        (4)成员内部类  (外部类没有static作为修饰,而内部类则可以用static修饰,因为内部类把他看做外部类的成员来看待,成员是可以用静态修饰的)
             A:private 为了保证数据的安全性  身体类(包含心脏类,肝脏类,肺类等,这些都用私有内部类)
            B:static 为了让数据访问的方便性  ,内部类用静态修饰是因为内部类可以看出是外部类的成员,一般使用static修饰内部类的话,会用public作为访问修饰符,因为已经在类加载是加载了,算是顶层类,一般这样用不用构造方法,直接类名加方法就好了,所以,一般公用的才使用public

                   被静态修饰的成员内部类只能访问外部类的静态成员

                  内部类方法被静态修饰后的方法:1.静态方法2.非静态方法
            
            成员内部类不是静态的:
                外部类名.内部类名 对象名 = new 外部类名().new 内部类名();  例子:Outer.Inner oi = new Outer().new Inner();
            成员内部类是静态的:
                外部类名.内部类名 对象名 = new 外部类名.内部类名();  例子:Outer.Inner oi = new Outer.Inner();   

      (5)成员内部类的面试题(填空) 

    /*
          面试题:
                要求请填空分别输出30,20,10。
            
          注意:
                1:内部类和外部类没有继承关系。
                2:通过外部类名限定this对象
                      Outer.this
    */
    class Outer {
        public int num = 10;
        class Inner {
            public int num = 20;
            public void show() {
                int num = 30;
                System.out.println(num);  //就近原则下的num
                System.out.println(this.num);  //本类下的成员变量num
                //System.out.println(new Outer().num);   //这句是可以的,创建一个匿名对象调用变量,但不是最简单,最简单在下面
                System.out.println(Outer.this.num);  //利用Outer.this,限制this的范围,来访问Outer下的num
            }
        }
    }
    class InnerClassTest {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer().new Inner();
            oi.show();
        }    
    }


        (6)局部内部类(这个点很容易被忽视)

            可以直接访问外部类的成员
            可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
            局部内部类访问局部变量的注意事项:
            A:局部内部类访问局部变量必须加final修饰。
            B:为什么呢?
                因为局部变量是随着方法的调用而调用,随着调用完毕而消失。而堆内存的数据并不会立即消失。
                所以,堆内存还是用该变量,而该变量已经没有了。
                为了让该值还存在,就加final修饰。
                通过反编译工具我们看到了,加入final后,这个变量就成了常量,堆内存直接存储的是值,而不是变量名。
    局部内部类例子,面试题:

    /*
        局部内部类
            A:可以直接访问外部类的成员
            B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
        
        面试题:
            局部内部类访问局部变量的注意事项?
            A:局部内部类访问局部变量必须用final修饰
            B:为什么呢?
                局部变量是随着方法的调用而调用,随着调用完毕而消失。
                而堆内存的内容并不会立即消失。所以,我们加final修饰。
                加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
                我在内存中存储的是数据20,所以,我还是有数据在使用。
    */
    class Outer {
        private int num  = 10;
        
        public void method() {
            //int num2 = 20;  //jdk报错,说明一定要final作为局部变量的修饰
            final int num2 = 20;//对的
            class Inner {
                public void show() {
                    System.out.println(num);
                    //从内部类中访问本地变量num2; 需要被声明为最终类型,可以利用反编译穿软件看看,是否直接变为20,连变量名都消失了
                    System.out.println(num2);//20
                }
            }
            
            //System.out.println(num2);
            
            Inner i = new Inner();
            i.show();
        }
    }

    class InnerClassDemo5 {
        public static void main(String[] args) {
            Outer o = new Outer();
            o.method();
        }
    }
      

      (7)匿名内部类(掌握)
            A:其实是局部内部类的简化形式
            B:前提
                存在一个类或者接口,这里的类可以是具体类也可以是抽象类
            C:格式:
                new 类名或者接口名() {
                    重写方法;
                }
            D:本质:
                其实是继承该类(具体类对象)或者实现接口的子类(实现类)匿名对象

            E:好处:在使用匿名对象或匿名内部类时,都是一次定义,一次使用就不会用了,所以不用创建引用变量指向对象引用地址,匿名的使用能让jvm的垃圾回收机制快点收回内存,因为它没有被栈的变量所指向,所以回收速度最快。

              弊端:只能使用一次
      

        (8)匿名内部类在开发中的使用
            我们在开发的时候,会看到抽象类,或者接口作为参数。
            而这个时候,我们知道实际需要的是一个子类对象。
            如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
           例子:

    /*
        匿名内部类在开发中的使用
    */
    interface Person {
        public abstract void study();
    }

    class PersonDemo {
        //接口名作为形式参数
        //其实这里需要的不是接口,而是该接口的实现类的对象
        public void method(Person p) {
            p.study();
        }
    }

    //实现类
    class Student implements Person {
        public void study() {
            System.out.println("好好学习,天天向上");
        }
    }

    class InnerClassTest2 {
        public static void main(String[] args) {
            //测试
            PersonDemo pd = new PersonDemo();
            Person p = new Student();
            pd.method(p);
            System.out.println("--------------------");
            
            //匿名内部类在开发中的使用
            //匿名内部类的本质是继承类或者实现了接口的子类匿名对象
            pd.method(new Person(){
                public void study() {
                    System.out.println("好好学习,天天向上");
                }
            });
        }
    }


        (9)匿名内部类的面试题(补齐代码)
    /*
        匿名内部类面试题:
            按照要求,补齐代码
                interface Inter { void show(); }
                class Outer { //补齐代码 }
                class OuterDemo {
                    public static void main(String[] args) {
                          Outer.method().show();
                      }
                }
                要求在控制台输出”HelloWorld”
    */
    interface Inter {
        void show();
        //public abstract
    }

    class Outer {
        //补齐代码
        public static Inter method() {
            //子类对象 -- 子类匿名对象
            return new Inter() {
                public void show() {
                    System.out.println("HelloWorld");
                }
            };
        }
    }

    class OuterDemo {
        public static void main(String[] args) {
            Outer.method().show();
            /*
                1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
                2:Outer.method().show()可以看出method()方法的返回值是一个对象。
                    又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
            */
        }
    }

  • 相关阅读:
    String 类的常用方法都有那些?
    == 和 equals 的区别是什么
    java【Scanner,Random,ArrayList】的用法(了解80%~90%)
    java无参与有参以及setter和getter方法(练习题)【就事论事】
    java无参与有参以及setter和getter方法(了解)
    不能只学习,还得有玩
    java封装方法(了解)
    java数组,冒泡排序,选择排序(了解80%~90%)
    关于LDEA软件设置背景(详细)
    java运算符,判断符(了解)
  • 原文地址:https://www.cnblogs.com/canceler/p/4602952.html
Copyright © 2020-2023  润新知