第十讲

Java语言基础第十讲

一.package关键字的概述及作用

  • 包(package)
    • 将字节码(.class)进行分类存放 
    • 包其实就是文件夹
  • 定义包的格式
    • package 包名;
    • 多级包用.分开即可
    • package com.heima;
  • 定义包的注意事项

    • package语句必须是程序的第一条可执行的代码
    • package语句在一个java文件中只能有一个
    • 如果没有package,默认表示无包名

      package com.heima;
      class Demo1_Package {
          public static void main(String[] args) {
              System.out.println("Hello World!");
          }
      }
      
  • 带包的类编译和运行

    • 如何编译运行带包的类(javac编译的时候带上-d即可)
      • javac -d . 类名.java
    • 通过java命令执行。
      • java 包名.类名
  • 不同包下类之间的访问

    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;
        }
    }
    

二.import关键字的概述和使用

  • 为什么要有import
    • 其实就是让有包的类对调用者可见,不用写全类名了 
    • 导包后Person类对于Demo1_Package就可见了
  • 导包格式
    • import 包名;
    • 注意:
    • 这种方式导入是到类的名称。
    • 虽然可以最后写*,但是不建议。
  • package,import,class有没有顺序关系(面试题)

    • package是第一行可执行语句(只能有一句),import(可以写很多句)在类class上面.

      package com.heima;
      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;
          }
      }
      

三.四种权限修饰符的测试

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

    • private (类访问级别):private修饰的,只能在本类中访问;
    • 默认修饰符(包访问级别default):可以在本类中访问同一个包下的所有类;
    • prodected(子类访问级别):protected修饰的,可在本类中访问,同一个包下的所有类也能访问,不同包下的子类也可以访问,但在不同包下的无关类不能访问.
    • public(公共访问级别):能访问同包,不同包子下的所有类和类成员.

      package com.heima;
      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();
          }
      }
      

四.类及其组成所使用的常见修饰符

  • 修饰符:
    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract
  • 类:
    • 权限修饰符:默认修饰符,public,外部类不能用私有的
    • 状态修饰符:final
    • 抽象修饰符:abstract
    • 用的最多的就是:public
  • 成员变量:
    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,fina
    • 用的最多的就是:private
  • 构造方法:
    • 权限修饰符:private,默认的,protected,public
    • 用的最多的就是:public
  • 成员方法:

    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • 除此以外的组合规则:

    • 成员变量:public static final
    • 成员方法:
          * public static 
          * public abstract
          * public final

五.内部类概述和访问特点

  • 内部类概述
    • 定义在类中的类
  • 内部类访问特点

    • 内部类可以直接访问外部类的成员,包括私有。
    • 外部类要访问内部类的成员,必须创建对象。
    • 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    • Outer.Inner oi = new Outer().new Inner();

      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);
              }
          }
      }   
      
  • 成员内部类私有使用

    • 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();
          }
      }
      
  • 静态成员内部类

  • 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");
              }
          }
      }
      
  • 成员内部类的面试题

  • 面试题

    要求:使用已知的变量,在控制台输出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();
        }   
    }
    
  • 局部内部类访问局部变量的问题

    • 局部内部类访问局部变量必须用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();
            }*/
        }
        

六.匿名内部类的格式和理解

  • 匿名内部类
    • 就是内部类的简化写法。
  • 前提:存在一个类或者接口
    • 这里的类可以是具体类也可以是抽象类。
  • 格式:
     

    new 类名或者接口名(){
        重写方法;
    }
    
  • 本质

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

      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();
          }
      }
      
  • 匿名内部类重写多个方法调用

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

      class Demo2_NoNameInnerClass {
          public static void main(String[] args) {
              Outer o = new Outer();
              o.method();
          }
      }
       
      interface Inter {
          public void show1();
          public void show2();
      }
      //匿名内部类只针对重写一个方法时候使用看vv
      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();                        //匿名内部类是不能向下转型的,因为没有子类类名
          }
      }
      
  • 匿名内部类在开发中的应用

    //这里写抽象类,接口都行
    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");
        }
    }
    
  • 匿名内部类的面试题

    按照要求,补齐代码
    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”
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值