• 匿名类、包、权限修饰符_DAY10


    1:内部类(理解)

          (1)把类定义在一个类的内部。

          (2)特点:

               A:内部类可以直接使用外部类的成员,包括私有。

               B:外部类要使用内部类成员,必须创建对象使用。

               例子:

    public class InnerClassTest {
        public static void main(String[] args) {
            OuterClass.InnerClass inner=new OuterClass().new InnerClass();//创建内部类对象
            inner.innerMethod(); //外部类要使用内部类成员,必须创建对象使用
        }
    }
    
    class OuterClass{
        //成员变量
        private int age=10;
        //构造方法
        public OuterClass(){}
    
        //成员内部类
        class InnerClass{
           public void innerMethod(){
               System.out.println("我是成员内部类,访问外部类的私有属性age:"+age);
               //内部类可以直接使用外部类的成员,包括私有。
           }
        }
    }
    View Code

          (3)内部类的分类:

               局部内部类:定义在方法中的内部类

               成员内部类:定义在类中方法外的内部类

          (4)成员内部类

               class Outer {

                   class Inner {  //成员内部类

                   }

               }

             普通的修饰的时候:

                 外部类名.内部类名 变量 = 外部类对象.内部类对象;

                 Outer.Inner oi = new Outer().new Inner();

              class Outer {

                   static class Inner {

                        void method(){}

                 }

             }

             用静态修饰内部类时:

                   外部类名.内部类名 变量 = 外部类名.内部类对象

                   Outer.Inner oi = new Outer.Inner();

                   Outer.Inner oi = Outer.new Inner(); //错误

             用静态修饰内部类和方法时:

                   Outer.Inner.method()

             成员内部类:

                 private:为了数据的安全。可以加数据校验

                 static:为了方便调用。

             例子:

    /*
        成员内部类:
            内部类定义在成员位置
        内部类对象创建:
            Outer.Inner x = new Outer().new Inner();
    */
    class Demo8 
    {
        public static void main(String[] args) 
        {
            //Inner inner = new Inner();   //内部类对象不可以直接这样创建
            //System.out.println(new Outer().age); //调用错误
    
        
                    Outer out = new Outer();
            Outer.Inner inner = out.new Inner(); //创建内部类对象的方式1
            Outer.Inner inner2 = new Outer().new Inner();//创建内部类的对象的方式2
            
                    inner.innerMethod();
                    inner2.innerMethod();
       
        }
    }
    
    class Outer
    {
            //成员属性
        private int age;
            
            //成员内部类
        class Inner
        {
            public void innerMethod(){
                System.out.println("我是内部类的方法,外部类age的值为"+age); //可以直接访问外部私有属性
            }
        }
            
            //成员方法
        public void outerMethod(){
            Inner inner = new Inner(); //创建成员内部类对象,调用成员内部类方法
            inner.innerMethod();
        }
    }
    View Code
    /*
        private与static修饰符的成员内部类
        private:外界无法直接创建内部类对象,外部类可以创建内部类对象,在此之前可以加入校验。
        static: 修饰内部类,不需要使用外部类对象,外部类名直接调用,修饰内部类成员,不需要内部类对象,使用内部类名直接调用。
    */
    class Demo9 
    {
        public static void main(String[] args) 
        {
            /*private-----------------------------------------------------------------------
    
            //当使用private修饰成员内部类,则不能使用以下两种方法创建对象
                    //Outer out = new Outer();
            //Outer.Inner2 inner = out.new Inner2(); //方式1
            //Outer.Inner2 inner = new Outer().new Inner2();//方式2
            
            //可以在外部类的方法中创建内部类对象,可以增加数据校验,保证安全性
            out.outerMethod();
            */
    
    
                    //static---------------------------------------------------------------------
            //当使用static修饰成员内部类,可以直接使用外部类名new Outer.innerMethod()的形式创建内部类对象
            Outer.Inner inner= new Outer.Inner();
            inner.innerMethod();
    
                    //当使用static修饰成员内部类,同时成员内部类的方法也用static修饰时,可以直接使用外部类.内部类.方法的形式,调用内部类的方法!
            Outer.Inner.innerStaticMethod();
        }
    }
    
    class Outer
    {
        private static int age;
    
        static class Inner
        {
            public void innerMethod(){
                System.out.println("我是内部类的方法,外部类age的值为"+age);
            }
    
            public static void innerStaticMethod(){
                System.out.println("我是内部类的方法,外部类age的值为"+age);
            }
        }
    
        public void outerMethod(){
            //数据校验
            Inner inner = new Inner();
            inner.innerMethod();
        }
    }
    
    
    class Outer2
    {
        private int age2;
    
        private class Inner2
        {
            public void innerMethod2(){
                System.out.println("我是内部类的方法,外部类age的值为"+age2);
            }
        }
    
        public void outerMethod2(){
            //数据校验
            Inner inner2 = new Inner2();
            inner2.innerMethod2();
        }
    }
    View Code

          (5)局部内部类

               A:带名字的局部内部类

                     class Outer {          //外部类

                            public void method() { //成员方法

                                  final int a = 10;

                                  class Inner {  //成员内部类

                                        public void show() {   //成员内部类的方法

                                               System.out.println("show");

                                               System.out.println(a);

                                           }

                                       }

                                  Inner i = new Inner(); //在成员内部类里面创建对象并使用!

                                  i.show();

                            }

                       }

             B:匿名内部类(掌握)

                   a:没有名字的内部类。其本质是一个对象。是通过多态来实现的。

                   b:前提:存在一个抽象类或者接口。

                   c:格式:

                      new 抽象类或者接口() {

                          重写父类方法;

                      };

                   本质:是一个继承了类或者实现了接口的子类匿名对象。

               例子:

    /*
        匿名内部类:
            在通过简写形式定义一个没有类名的类。
            匿名内部类即将匿名定义类与创建对象的动作一起完成。    
    
            必须要有实现或者继承关系。
    
            格式:
            new 类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)};  //注意使用的是父类或者接口
    
    */
    class Demo11 
    {
    
        public static void main(String[] args) 
        {
            Demo12 demo12 = new Demo12();
            demo12.outerMethod();
        }
        
    }
    
    abstract class Animal
    {
        public abstract void eat();
    }
    
    interface MyInterface
    {
        public abstract void method();
        public abstract void method2();
    }
    
    class Demo12
    {
        public void outerMethod(){
        
            class Cat extends Animal  //内部类
            {
                public void eat(){
                    System.out.println("舔着吃!");
                }
            }
            Animal cat = new Cat();
            cat.eat();
    
            System.out.println("============================");
    
            Animal anyAnimal = new Animal(){ //没有类名,有对象名
                public void eat(){
                    System.out.println("舔着吃!");
                }
    
                public void method(){
                    System.out.println("我是匿名内部类对象的方法");
                }
            };
            
            anyAnimal.eat();
            //anyAnimal.method();
    
            new Animal(){
                public void eat(){
                    System.out.println("舔着吃!");
                }
            }.eat();
    
            //===============================以上为抽象类的内部类,以下为接口的内部类
            System.out.println("============================");
    
            class MyClass implements MyInterface
            {
                    public void method() {
                        System.out.println("我是内部类方法1");
                    }
                    public void method2() {
                        System.out.println("我是内部类方法2");
                    }
            }
    
            MyInterface mi = new MyClass();//有类名MyClass,有对象名mi
            mi.method();
            mi.method2();
    
            MyInterface mi2 = new MyInterface(){//没有类名,有对象名mi2
                    public void method() {
                        System.out.println("我是匿名内部类方法1");
                    }
                    public void method2() {
                        System.out.println("我是匿名内部类方法2");
                    }
            };
    
            mi2.method();
            mi2.method2();
    
            new MyInterface(){    //没有类名,没有对象名,即匿名对象
                    public void method() {
                        System.out.println("我是匿名内部类方法1");
                    }
                    public void method2() {
                        System.out.println("我是匿名内部类方法2");
                    }
            }.method();
    
            
            new MyInterface(){ //没有类名,没有对象名,即匿名对象
                    public void method() {
                        System.out.println("我是匿名内部类方法1");
                    }
                    public void method2() {
                        System.out.println("我是匿名内部类方法2");
                    }
            }.method2();
        }
    }
    View Code

                   d.匿名内部类的使用场景 :

              :内部类效率更高。

              :通常在使用接口类型参数的方法上,并该接口中的方法不超过三个时,可以将匿名内部类作为参数传递。

              :增强阅读性。

                            例子:

    package package3;
    
    /*
        使用匿名内部类的场景:
            1:提高效率
            2:当参数类型,返回值类型,成员变量类型为抽象类或者接口时,可以使用匿名内部类。
            3:增强阅读性
    
    */
    class Demo13
    {
        public static void main(String[] args)
        {
            //-----------------普通方式调用  ---------------------
            Demo13 demo13 = new Demo13();
            MyClass mc = new MyClass();
            demo13.method(mc);
    
           //-----------------创建匿名内部类---------------------
            demo13.method(new MyInerface(){
                public void method() {
                    System.out.println("匿名对象匿名内部类方法一");
                }
                public void method2() {
                    System.out.println("匿名对象匿名内部类方法二");
                }
            });
    
    
            MyAbsClass mac = demo13.method2();
            mac.eat();
            mac.sleep();
            mac.hitBeanBean();
        }
    
        //参数类型为接口的方法
        public void method(MyInerface mi) {
            mi.method();
            mi.method2();
        }
        //返回值类型为抽象类的方法
        public MyAbsClass method2() {
            // 方式1:有类名MyClass2、有对象名mac
             /* 
            MyAbsClass mac = new MyClass2();
            return mac;
            */
           
            //方式2:没有类名,有对象名mac
            /*
            MyAbsClass mac = new MyAbsClass(){
                    public void eat() {
                        System.out.println("匿名内部类中:学完匿名内部类,就吃不下去了!");
                    }
                    public void sleep(){
                        System.out.println("匿名内部类中:学完匿名内部类,就睡不着了!");
                    }
            };
    
            return mac;
            */
    
            //方式3:没有类名,没有对象名
            return new MyAbsClass(){      //匿名内部类
                public void eat() {
                    System.out.println("匿名内部类中:学完匿名内部类,就吃不下去了!");
                }
                public void sleep(){
                    System.out.println("匿名内部类中:学完匿名内部类,就睡不着了!");
                }
            };
        }
    }
    
    //---------------------------接口--------------------------------------
    interface MyInerface
    {
        public abstract void method();
        public abstract void method2();
    }
    
    class MyClass implements MyInerface
    {
        public void method() {
            System.out.println("方法一");
        }
        public void method2() {
            System.out.println("方法二");
        }
    }
    
    //---------------------------抽象类--------------------------------------
    
    abstract class MyAbsClass
    {
        public abstract void eat();
        public abstract void sleep();
    
        public void hitBeanBean(){
            System.out.println("学完匿名内部类,就开始打豆豆!");
        }
    }
    
    //---------------------------非抽象类--------------------------------------
    class MyClass2 extends MyAbsClass
    {
        public void eat() {
            System.out.println("学完匿名内部类,就吃不下去了!");
        }
        public void sleep(){
            System.out.println("学完匿名内部类,就睡不着了!");
        }
    }
    View Code

                (6)例子:定义并使用内部类。要求包含局部内部类,成员内部类,匿名内部类。

    /**
     * 定义并使用内部类。要求包含局部内部类,成员内部类,匿名内部类。
     */
    public class Main {
        public static void main(String[] args) {
    
            //调用成员内部类
            Fu.Zi zi= new Fu().new Zi();
            zi.sleep();
    
    
            //调用局部内部类
            Fu fu=new Fu();
            fu.eat();
    
            //调用匿名内部类
            fu.method().eatType();
    
        }
    }
    View Code
    /**
     * 定义并使用内部类。要求包含局部内部类,成员内部类,匿名内部类。
     */
    public class Fu {
        //成员变量
        String string = "巴马";
    
        //成员内部类
        public class Zi {
            public void sleep() {
                System.out.println("睡觉");
            }
        }
    
        //局部内部类
        public void eat() {
            class EatMeat extends EatType {      //局部内部类,必须要继承抽像类或者继承接口
                public void eatType() {
                    System.out.println("吃肉");
    
                }
            }
            EatMeat eatMeat = new EatMeat();
            eatMeat.eatType();
        }
    
        //匿名内部类
        public EatType method() {  //返回值类型或者参数类型为抽象类或者接口
          /*EatType type= new EatType(){
                public void eatType(){
                    System.out.println("吃鱼");
                }
            };
          return type;*/
    
          return new EatType(){
                public void eatType(){
                    System.out.println("吃鱼");
                }
            };
    
        }
    
    }
    View Code
    public abstract class EatType {
        public abstract void eatType();
    }
    View Code

             (7)匿名内部类面试题

            

    /*
        匿名内部类练习:
            Outer.method.show();    意思为Outer类的静态成员变量method可以调用一个show方法,可以调用show方法的一定是Inter接口的子类实例
            Outer.method().show();  意思为Outer类的静态成员方法method()的返回值可以调用一个show方法,可以调用show方法的一定是Inter接口的子类实例
    */
    
    interface Inter{
        void show();
    }
    
    //题目1:
    class Outer{
        //补齐代码
        public static Inter method() {
                    //方式1
            /* 
            Inter inter = new Inter(){
                public void show(){
                    System.out.println("hello world");
                }
            };
            return inter;
            */
    
                    //方式2
            return new Inter(){
                public void show(){
                    System.out.println("hello world");
                }
            };
        }
    }
    
    class innerClassTest{
        public static void main(String[] args){
            Outer.method().show();
        }
    }
    
    
    //题目2:
    /*
    class Outer{
        //补齐代码
        public static Inter method = new Inter(){
            public void show(){
                System.out.println("hello world");
            }
        }; 
    }
    class innerClassTest{
        public static void main(String[] args){
            Outer.method.show();
            
        }
    } 
    */
    View Code

    2:包(掌握)

          (1)包就是永远区分相同类在不同文件夹下。其本质就是一个文件夹。

          (2)包的作用:让相同类名的类可以存在。为了组织代码。cn.itcast.action   cn.itcast.service  cn.itcast.db

          (3)定义包:

               package 包名.包名...;

          (4)带包的编译和运行(理解)

               A:方式一

                   手动式

                     a:javac编译代码

                     b:手动建立包,把class扔进去

                     c:java执行,带全路径

               B:方式二

                   自动式

                     a:通过javac编译自动生成包

                          javac -d . 文件名

                     b:通过java运行class文件

                       java 包名.包名.class文件名不带扩展名

          (5)不同包下的类之间的访问。

               权限够大才行。

             以后,我们所有定义的类都用public修饰。

          (6)面试题:

               在同一个java文件中,可不可以有多个类?可以。

               而我们知道类是可以用public修饰的,那么,可不可以多个类都用public修饰?不可以。

               并且,一般的时候,如果有main方法也存在的时候,都是public修饰带main那个类。

               文件名必须和该public修饰的类名一致。

          (7)实际运行的时候,是要求Class文件在一个文件加下,可以直接调用,如果不在一个文件夹下,导包也是为了导入Class文件。

    3:导包(掌握)

          (1)如果多次使用一个多级包的类,每次带全路径太麻烦,我们就考虑使用导包。

          (2)导包的格式:

               import 包名.包名...;

             注意:

                 在同一个包下如果有多个类被使用,可以使用通配符*来导入,但是不建议。

                 推荐:使用谁导入谁。

        (3)面试题:

           package,import,class出现的位置?

               package > import > class

    4:权限修饰符(掌握)

          (1)用于保证在不同的情况下可以使用

          (2)使用如下

                      本类     同一个包下   不同包下的子类   不同包下的无关类

             private    Y

             默认       Y       Y

             protected  Y      Y             Y

             public     Y       Y              Y              Y

        常见的组合规则:

           权限修饰符+abstract/final/static+...

        我们到底怎么用(开发的时候一般都这么做):

            类:

               public class Demo {       }

          成员变量:

               变量:private String name;  加上相应的getter和setter

               常量:public static final int X = 10;

          构造方法:

               不让外界创建:private Demo(){}

               大部分:public Demo(){}

          成员方法:

               不让外界用:private void show(){}

               大部分:public void method(){}

               抽象方法:public abstract void function();

  • 相关阅读:
    git command
    互联网应用架构概览-学习笔记
    机器学习基础概念-阿里大学课程学习笔记
    Python的并行求和例子
    C语言处理CSV数据
    Pattern Evaluation
    Python写的大小写转换小工具
    处理输入为非对角阵的Clustering by fast search and find of density peak代码
    css点击下层穿透上层元素
    浏览器全屏效果
  • 原文地址:https://www.cnblogs.com/hezhiyao/p/7504464.html
Copyright © 2020-2023  润新知