java 匿名内部类

###09.01_面向对象

(package关键字的概述及作用)(了解)

* A:为什么要有包

        *开发时有很多类,如果放在一个文件夹中不方便管理,而且容易重复

      * 将字节码(.class)进行分类存放 

      * 包其实就是文件夹

* B:包的概述

      举例:

           学生:增加,删除,修改,查询

           老师:增加,删除,修改,查询

           方案1:按照功能分

                 com.heima.add

                      AddStudent

                      AddTeacher

                 com.heima.delete

                      DeleteStudent

                      DeleteTeacher

                 com.heima.update

                      UpdateStudent

                      UpdateTeacher

                 com.heima.find

                      FindStudent

                      FindTeacher

          

           方案2:按照模块分

                 com.heima.teacher

                      AddTeacher

                      DeleteTeacher

                      UpdateTeacher

                      FindTeacher

                 com.heima.student

                      AddStudent

                      DeleteStudent

                      UpdateStudent

                      FindStudent

###09.02_面向对象(包的定义及注意事项)(掌握)

* A:定义包的格式

      * package 包名;

      * 多级包用.分开即可

* B:定义包的注意事项

      * A:package语句必须是程序的第一条可执行的代码

      * B:package语句在一个java文件中只能有一个

      * C:如果没有package,默认表示无包名

* C:案例演示

      * 包的定义及注意事项

案例:

package com.heima;

class Demo1_Package {

     public static void main(String[] args) {

          System.out.println("Hello World!");

     }

}

###09.03_面向对象(带包的类编译和运行)(掌握)

* A:如何编译运行带包的类

      * a:javac编译的时候带上-d即可

           * javac -d . HelloWorld.java

      * b:通过java命令执行。

           * java 包名.HellWord

 

 

###09.04_面向对象(不同包下类之间的访问)(掌握)

* A:案例演示

      * 不同包下类之间的访问

案例:

package com.heima;

class Demo1_Package {

     public static void main(String[] args) {

          com.baidu.Person p = new com.baidu.Person("张三",23);

          System.out.println(p.getName() + "..." + p.getAge())       

     }

}

 

package com.baidu;

public class Person {

     private String name;

     private int age;

 

     public Person(){}

 

     public Person(String name,int age) {

          this.name = name;

          this.age = age;

     }

 

     public void setName(String name) {

          this.name = name;

     }

 

     public String getName() {

          return name;

     }

 

     public void setAge(int age) {

          this.age = age;

     }

 

     public int getAge() {

          return age;

     }

}

 

 

###09.05_面向对象(import关键字的概述和使用)(掌握)

* A:案例演示

      * 为什么要有import

           * 其实就是让有包的类对调用者可见,不用写全类名了 

                *导包后Person类对于Demo1_Package就可见了

* B:导包格式

      * import 包名;

      * 注意:

      * 这种方式导入是到类的名称。

      * 虽然可以最后写*,但是不建议。

* C:package,import,class有没有顺序关系(面试题)

Package最上面

Import中间,可以写多行

Class最下面

 

案例

import com.baidu.Person;

import com.xxx.Student;

//import java.util.Scanner;         //在开发中我们用的都是导入具体的类

import java.util.*;                 //*代表通配符,他会到该包下挨个匹配,匹配上就导入

class Demo1_Package {

     public static void main(String[] args) {

          Person p = new Person("张三",23);

          System.out.println(p.getName() + "..." + p.getAge());

          //p.print();             //在不同包下的无关类,不允许访问,因为是protected修饰的

 

          /*Scanner sc = new Scanner(System.in);

          int x = sc.nextInt();

          System.out.println(x);*/      

     }

}

 

package com.baidu;

public class Person {

     private String name;

     private int age;

 

     public Person(){}

 

     public Person(String name,int age) {

          this.name = name;

          this.age = age;

     }

 

     public void setName(String name) {

          this.name = name;

     }

 

     public String getName() {

          return name;

     }

 

     public void setAge(int age) {

          this.age = age;

     }

 

     public int getAge() {

          return age;

     }

}

 

###09.06_面向对象(四种权限修饰符的测试)(掌握)

*封装:隐藏实现细节,对外提供公共的访问方式

* A:案例演示

      * 四种权限修饰符

* B:结论

                            本类      同一个包下(子类和无关类) 不同包下(子类)     不同包下(无关类)

           private              Y          

           默认                Y              Y

           protected  Y                 Y                                  Y

           public        Y                 Y                                  Y                    Y

案例:

import com.baidu.Person;

import com.xxx.Student;

//import java.util.Scanner;         //在开发中我们用的都是导入具体的类

import java.util.*;                 //*代表通配符,他会到该包下挨个匹配,匹配上就导入

class Demo1_Package {

     public static void main(String[] args) {

          Person p = new Person("张三",23);

          System.out.println(p.getName() + "..." + p.getAge());

          //p.print();             //在不同包下的无关类,不允许访问,因为是protected修饰的

 

          /*Scanner sc = new Scanner(System.in);

          int x = sc.nextInt();

          System.out.println(x);*/

         

          Student s = new Student("李四",24);

          System.out.println(s.getName() + "..." + s.getAge());

          s.method();

     }

}

 

package com.baidu;

public class Person {

     private String name;

     private int age;

 

     public Person(){}

 

     public Person(String name,int age) {

          this.name = name;

          this.age = age;

     }

 

     public void setName(String name) {

          this.name = name;

     }

 

     public String getName() {

          return name;

     }

 

     public void setAge(int age) {

          this.age = age;

     }

 

     public int getAge() {

          return age;

     }

 

     protected void print() {

          System.out.println("print");

     }

}

 

package com.xxx;

import com.baidu.Person;

public class Student extends Person {

     public Student(){}

 

     public Student(String name,int age) {

          super(name,age);

     }

 

     public void method() {

          print();

     }

}

 

###09.07_面向对象(类及其组成所使用的常见修饰符)(掌握)

* A:修饰符:

      * 权限修饰符:private,默认的,protected,public

      * 状态修饰符:static,final

      * 抽象修饰符:abstract

* B:类:

      * 权限修饰符:默认修饰符,public,外部类不能用私有的

      * 状态修饰符:final

      * 抽象修饰符:abstract

      * 用的最多的就是:public

     

* C:成员变量:

      * 权限修饰符:private,默认的,protected,public

      * 状态修饰符:static,final

      * 用的最多的就是:private

     

* D:构造方法:

      * 权限修饰符:private,默认的,protected,public

      * 用的最多的就是:public

     

* E:成员方法:

      * 权限修饰符:private,默认的,protected,public

      * 状态修饰符:static,final

      * 抽象修饰符:abstract

      * 用的最多的就是:public

     

* F:除此以外的组合规则:

      * 成员变量:public static final

      * 成员方法:

          * public static 

          * public abstract

          * public final

 

###09.08_面向对象(内部类概述和访问特点)(了解)

* A:内部类概述

* B:内部类访问特点

      * a:内部类可以直接访问外部类的成员,包括私有。

      * b:外部类要访问内部类的成员,必须创建对象。

      * 外部类名.内部类名 对象名 = 外部类对象.内部类对象;

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

* C:案例演示

      * 内部类极其访问特点

案例:

class Demo1_InnerClass {

     public static void main(String[] args) {

          //Inner i = new Inner();

          //i.method();

          //外部类名.内部类名 = 外部类对象.内部类对象

          Outer.Inner oi = new Outer().new Inner();            //创建内部类对象

          oi.method();

     }

}

class Outer {

     private int num = 10;

     class Inner {

          public void method() {

               System.out.println(num);

          }

     }

}   

 

###09.09_面向对象(成员内部类私有使用)(了解)

* private:在外部不能直接创建内部类对象了

案例:

class Demo2_InnerClass {

     public static void main(String[] args) {

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

          //oi.method();

          Outer o = new Outer();

          o.print();

     }

}

 

class Outer {

     private int num = 10;

     private class Inner {

          public void method() {

               System.out.println(num);

          }

     }

 

     public void print() {

          Inner i = new Inner();

          i.method();

     }

}

 

###09.10_面向对象(静态成员内部类)(了解)

* static

* B:成员内部类被静态修饰后的访问方式是:

      * 外部类名.内部类名 对象名 = 外部类名.内部类对象;

案例:

class Demo1_InnerClass {

     public static void main(String[] args) {

          //外部类名.内部类名 对象名 = 外部类名.内部类对象;

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

          oi.method();

          Outer.Inner2.print();

     }

}

 

class Outer {

     static class Inner {

          public void method() {

               System.out.println("method");

          }

     }

 

     static class Inner2 {

          public static void print() {

               System.out.println("print");

          }

     }

}

###09.11_面向对象(成员内部类的面试题)(掌握)

* A:面试题

           要求:使用已知的变量,在控制台输出30,20,10。

          

class Outer {

               public int num = 10;

               class Inner {

                    public int num = 20;

                    public void show() {

                         int num = 30;

                         System.out.println(?);//num

                         System.out.println(??);//this.num

                         System.out.println(???);//Outer.this.num,内部类之所以能够访问外部类成员,因为它获取了外部类的引用Outer.this

                    }

               }

          }

          class InnerClassTest {

               public static void main(String[] args) {

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

                    oi.show();

               }   

          }

 

###09.12_面向对象(局部内部类访问局部变量的问题)(掌握)

* A:案例演示

      局部内部类访问局部变量必须用final修饰

      * 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?

           因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用

 

           但是jdk1.8取消了这个事情,所以我认为这是个bug

案例:

class Demo1_InnerClass {

     public static void main(String[] args) {

          Outer o = new Outer();

          o.method();

     }

}

//局部内部类

class Outer {

     public void method() {

          final int num = 10;

          class Inner {//局部内部类和局部变量一样,只在方法中有效,出了方法就无效了

               public void print() {

                    System.out.println(num);

               }

          }

 

          Inner i = new Inner();

          i.print();

     }

 

     /*public void run() {

          Inner i = new Inner();                   //局部内部类,只能在其所在的方法中访问

          i.print();

     }*/

}

 

 

###09.13_面向对象(匿名内部类的格式和理解)

* A:匿名内部类

      * 就是内部类的简化写法。

* B:前提:存在一个类或者接口

      * 这里的类可以是具体类也可以是抽象类。

* C:格式:

           new 类名或者接口名 () {

                 重写方法;

           } ;

* D:本质是什么呢?

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

* E:案例演示

      * 按照要求来一个匿名内部类

案例:

class Demo1_NoNameInnerClass {

     public static void main(String[] args) {

          Outer o = new Outer();

          o.method();

     }

}

interface Inter {

     public void print();

}

 

class Outer {

     class Inner implements Inter {

          public void print() {

               System.out.println("print");

          }

     }

 

     public void method(){

          //Inner i = new Inner();

          //i.print();

          //new Inner().print();

          //Inter i = new Inner();            //父类引用指向子类对象

         

          new Inter() {                            //实现Inter接口

               public void print() {               //重写抽象方法

                    System.out.println("print");

               }

          }.print();

     }

}

 

          

###09.14_面向对象(匿名内部类重写多个方法调用)

* A:案例演示

      * 匿名内部类的方法调用

案例:

class Demo2_NoNameInnerClass {

     public static void main(String[] args) {

          Outer o = new Outer();

          o.method();

     }

}

 

interface Inter {

     public void show1();

     public void show2();

}

//匿名内部类只针对重写一个方法时候使用

class Outer {

     public void method() {

          /*new Inter(){

               public void show1() {

                    System.out.println("show1");

               }

 

               public void show2() {

                    System.out.println("show2");

               }

          }.show1();

 

          new Inter(){

               public void show1() {

                    System.out.println("show1");

               }

 

               public void show2() {

                    System.out.println("show2");

               }

          }.show2();*/

 

          Inter i = new Inter(){

               public void show1() {

                    System.out.println("show1");

               }

 

               public void show2() {

                    System.out.println("show2");

               }

 

               /*public void show3() {

                    System.out.println("show3");

               }*/

          };

 

          i.show1();

          i.show2();

          //i.show3();                             //匿名内部类是不能向下转型的,因为没有子类类名

     }

}

 

###09.15_面向对象(匿名内部类在开发中的应用)

* A:代码如下

          

//这里写抽象类,接口都行

          abstract class Person {

               public abstract void show();

          }

    

          class PersonDemo {

               public void method(Person p) {

                    p.show();

               }

          }

    

          class PersonTest {

               public static void main(String[] args) {

                    //如何调用PersonDemo中的method方法呢?

                    PersonDemo pd = new PersonDemo ();

                   

               }

          }

 

答案:

class Test1_NoNameInnerClass {

     public static void main(String[] args) {

          //如何调用PersonDemo中的method方法呢?

          PersonDemo pd = new PersonDemo ();

          //pd.method(new Student());

          pd.method(new Person() {

               public void show() {

                    System.out.println("show");

               }

          });

     }

}

//这里写抽象类,接口都行

abstract class Person {

     public abstract void show();

}

 

class PersonDemo {

    

     //public void method(Person p) {         //Person p = new Student();      //父类引用指向子类对象

     /*

     Person p = new Person(){

          public void show() {

               System.out.println("show");

          }

     };

     */

     public void method(Person p) {

          p.show();

     }

}

 

class Student extends Person {

     public void show() {

          System.out.println("show");

     }

}

 

 

###09.16_面向对象(匿名内部类的面试题)

* A:面试题

           按照要求,补齐代码

           interface Inter { void show(); }

           class Outer { //补齐代码 }

           class OuterDemo {

                 public static void main(String[] args) {

                        Outer.method().show();

                   }

           }

           要求在控制台输出”HelloWorld”

答案:

class Test2_NoNameInnerClass {

      public static void main(String[] args) {

           //Outer.method().show();            //链式编程,每次调用方法后还能继续调用方法,证明调用方法返回的是对象

           Inter i = Outer.method();

           i.show();

      }

}

//按照要求,补齐代码

interface Inter { 

      void show(); 

}

 

class Outer { 

      //补齐代码 

      public static Inter method() {

           return new Inter() {

                 public void show() {

                      System.out.println("show");

                 }

           };

      }

}

 

//要求在控制台输出”HelloWorld”

 

一、包【了解】

      1、其实就是文件夹,用来管理.class文件

 

      2、定义格式

           package com.itheima.basic

 

      3、注意事项

           A:必须是程序的第一条可执行语句

           B:一个源文件只能有一个package语句

           C:可以没有包名

 

      4、编译和运行带包的类

           编译: javac -d . Demo1.java

           运行: java com.itheima.Demo1

 

//-------------------------------------------------------------------------------

 

二、权限修饰符【掌握】

           private      本类

           默认的       本类     同包

           protected  本类     同包     不同包子类

           public        本类     同包     不同包子类      不同包无关类

 

           常见用法:

                 成员变量:private

                 构造方法:public

                 成员方法:public

 

//-------------------------------------------------------------------------------

 

三、内部类

      1、定义在一个类的内部的类就叫内部类

 

      2、访问特点

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

           B:外部类不可以直接访问内部类成员,必须通过创建内部类对象去访问

 

      3、分类

           A:成员内部类

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

 

           B:静态内部类

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

 

           C:局部内部类

                 局部内部类访问局部变量,局部变量一定要加final修饰

 

                 /*为什么?

                      因为局部变量的生命周期和方法是一致的,方法执行完毕弹栈,局部变量消失,

                      但是这时候局部内部类的对象还在堆内存中,局部内部类对象有可能还想再去使用这个局部变量。而局部变量却消失,很伤感,没有找到,所以报错。

                      所以需要加final修饰!

                      final修饰的变量是常量,常量随着类的加载而加载进方法区中的常量池。就算方法弹栈了,但常量池中的常量还在。局部内部类对象可以随时去访问,就不报错。

 

                 但是:

                      JDK1.8取消了这个限制。局部变量不用final, 局部内部类也可以使用。(面试的时候说一说,提高逼格)*/

 

      4、匿名内部类【掌握】

           A:匿名内部类属于局部内部类

 

           B: 格式

                 /*

                 new 抽象类/接口 () {

                      重写抽象方法;

                 }

                 */

 

           C:本质

                 是一个继承了该类或实现了该接口的匿名的子类对象

 

           D:应用场景

                 当做参数传递

                 当你发现一个方法的形式参数是一个抽象类或接口的时候,在调用这个方法的时候就可以使用匿名内部类。

 

                 eg:

                 interface Inter {

                      public abstract void show();

                 }

 

                 class Demo {

                      public void method(Inter i) {

                            i.show();

                      }

                 }

 

                 class Test {

                      public static void main(String[] args) {

                            Demo d = new Demo();

                            d.method(new Inter(){

                                  public void show(){

                                       System.out.println("SHOW");

                                  }

                            });

                      }

                 }

匿名内部类在编绎的时候会产生一个$符,没有名字的分别是$1.   $2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值