【172天】黑马程序员27天视频学习笔记【Day10】

叨逼叨两句

  1. 我勒个去,不要小看这一天的内容啊,真特么多,看来我Java继承还真挺一般的,还要继续努力!
  2. 明天复习这10天内容。

10-(01-05):package与import

package关键字概述及作用

  1. 就是文件夹
  2. 按功能划分或者按模块划分
  3. 增删改查

包的定义及注意事项

  1. package语句在java文件中只能有一个
  2. 如果没有package,默认表示没有包名
  3. package语句必须是程序的第一条可执行代码
  4. 该视频值得在看一遍

带包的类编译和运行

  1. 用javac编译test.java应该这样:javac -d . test.java这样编译后生成的class文件路径将是com/heima/test.class
  2. .代表当前目录,这里也可以改成别的目录。
  3. 要运行这样一个文件,需要在创建这个包的目录打开命令行运行`java
    com.heima.test`
package com.heima;

public class test {

}
  1. 该视频值得在看一遍

import关键字的概述和使用

  1. 作用:让那些带包的类,对调用其的类可见
package com.heima;
import com.baidu.Person;
class Test {
    public static void main(String[] args) {
        Person a = new Person();
        System.out.println(a.getName());
    }
}
package com.baidu;
class Person {
    private String name;
    
    public String getName(){
        return name;
    } 
}
  1. *通配符开发一般不用,因为它需要检索,挨个匹配,降低效率。

10-(06-07)

权限修饰符权限说明

                   本类   同一个包下(子类和无关类)  不同包下(子类)    不同包下(无关类)
private        Y       
默认(default)   Y         Y
protected      Y         Y                    Y
public         Y         Y                    Y               Y

修饰符使用一览


修饰符类别
  1. 权限修饰符:private、default、protected、public
  2. 状态修饰符:static、final
  3. 抽象修饰符:abstract
  1. 权限修饰符:default、public(常用)
  2. 状态修饰符:final
  3. 抽象修饰符:abstract
成员变量
  1. 权限修饰符:private(常用)、default、protected、public
  2. 状态修饰符:static、final
  3. 抽象修饰符:无
成员方法
  1. 权限修饰符:private、default、protected、public
  2. 状态修饰符:static、final
  3. 抽象修饰符:abstract
构造方法
  1. 权限修饰符:private、default、protected、public
  2. 状态修饰符:无
  3. 抽象修饰符:无
其它组合规则
  1. 成员变量:public static final
  2. 成员方法:

    1. public static
    2. public abstract
    3. public final
  3. abstract和final、static、private不可同时使用

10-(08-16)内部类

内部类概述及访问特点

  1. 内部类可以直接访问外部类的成员,包括私有
  2. 外部类要访问内部类的成员,必须创建对象。

    外部类.内部类 p = 外部类对象.内部类对象
        package test_heima_08;
    
    public class Test_Demo07 {
        public static void main(String[] args){
            Outer.Inner p = new Outer().new Inner();
            p.test();
        }
    }
    
    
    class Outer {
        class Inner {
            public void test(){
                System.out.println("Hello");
            }
        }
    }

私有成员内部类的调用方法

在外部类里面创建一个成员方法,然后在该成员方法内创建对象调用内部类的方法。

package test_heima;

public class Test_Demo08 {
    public static void main(String[] args){
        Outer2 a = new Outer2();
        a.kkk();
        
    }
}

class Outer2 {
    private int age = 1;
    
    private class Inner2 {
        public void test(){
            System.out.println("test");
        }
    }

    public void kkk(){
        Inner2 a = new Inner2();
        a.test();
    }
}

静态内部类的调用

package test_heima;

public class Test_Demo09 {
    public static void main(String[] args){
        
        //外部类.内部类 对象名 = 外部类名.内部类对象
        //其实逻辑上应该是 Outer3.Inner oi = Outer3.new Inner();
        //但是这样写不符合习惯,所有还是把new放左边了
        Outer3.Inner oi = new Outer3.Inner();
        oi.method();
        
        //外部类名.内部类名.方法名
        Outer3.Inner.method2();
    }
}

class Outer3 {
    static class Inner {
        public void method() {
            System.out.println("非静态方法调用");
        }
        
        public static void method2() {
            System.out.println("静态方法调用");
        }
    }
}

内部类成员对不同成员变量的调用(重要!!!)

package test_heima;

public class Test_Demo10 {
    public static void main(String[] args){
        Outer4.Inner oi = new Outer4().new Inner();
        oi.show();
    }
}

class Outer4 {
    public int a = 3;
    class Inner {
        public int a = 2;
        public void show(){
            int a = 1;
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(Outer4.this.a);
        }
    }
}

局部内部类里面的方法调用方式

  1. 局部内部类开发用的很少
  2. 局部内部类里面的方法调用方式

        package test_heima;
    
    public class Test_Demo11 {
        public static void main(String[] args){
            Outer6 p = new Outer6();
            p.method();
        }
    }
    
    class Outer6 {
        
        public void method(){
            
            class Inner {
                public void test(){
                    System.out.println("Hello");
                }
            }
        
            Inner si = new Inner();
            si.test();
            
        }
    }
    

局部内部类访问局部变量的方式

  1. 在JDK1.7中,局部内部类访问他所在的方法中的局部变量时,需要加上final修饰符。但是JDK1.8中不需要了,估计是个bug。
  2. 局部内部类访问他所在的方法中的局部变量必须用final修饰,为什么?因为调用这个方法时,局部变量如果没有final修饰符修饰,其生命周期和方法相同,将会随着方法的弹栈而消失,那么若局部内部类的对象还没有从堆中消失,想要使用这个局部变量,就没有了,但若加上final,在类加载时,该常量将会进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用。
package test_heima;

public class Test_Demo12 {
    public static void main(String[] args){
        Outer7 a = new Outer7();
        a.method();
    }
}

class Outer7 {
    public void method(){
        
        int a = 1; //在JDK1.7中这样写不行,需要加final,让局部变量进入常量池,保证在方法弹栈后,对象依然可以访问。
        
        class Inner {
            public void test(){
                System.out.println(a);
            }
        }
        
        Inner si = new Inner();
        si.test();
    }
}

匿名内部类的使用格式和理解

  1. 匿名内部类是内部类的简化写法
  2. 匿名内部类是局部内部类的一种,必须写在方法里。
  3. 前提:存在一个类(方便匿名内部类继承,这个类可以是具体类,也可以是抽象类)或者接口(方便匿名内部类实现)
  4. 格式:

    new 类名或者接口名(){
        重写方法;
    }
  5. 本质:一个继承成了该类或者实现了该接口的子类匿名对象。
package test_heima;

public class Test_Demo13 {
    public static void main(String[] args){
        Outer8 si = new Outer8();
        si.method();
    }
}

interface Inter {
    public void test();
}

class Outer8 {
    class Inner implements Inter {
        public void test(){
            System.out.println("Hello");
        }
    }
    
    public void method(){
        //如何调用test()?
        //法1:有名字a
//        Inner a = new Inner();
//        a.test();
        
        //法2:匿名
        new Inter(){
            public void test(){
                System.out.println("Hello");
            }
        }.test();
        
    }
    
}

匿名内部类重写多个方法的情况

  1. 匿名内部类适用于一次性使用,多次调用建议使用有名的内部类。

    package test_heima;
    
    public class Test_Demo14 {
        public static void main(String[] args){
            Outer11 si = new Outer11();
            si.method();
        }
    }
    
    interface Inter2 {
        public void print1();
        public void print2();
    }
    
    class Outer11 {
        public void method(){
            
            //这样多次调用使用匿名内部类并不方便,建议多次调用使用有名的内部类。
            new Inter2(){
                public void print1(){
                    System.out.println("print1");
                }
                
                public void print2(){
                    System.out.println("print2");
                }
            }.print1();
            
            new Inter2(){
                public void print1(){
                    System.out.println("print1");
                }
                
                public void print2(){
                    System.out.println("print2");
                }
            }.print2();
        }
    }
  2. 可以将父类引用指向子类对象,但是,由于匿名对象没类名,无法实现向下转型,所以无法使用子类特有的方法。

    package test_heima;
    
    public class Test_Demo14 {
        public static void main(String[] args){
            Outer11 si = new Outer11();
            si.method();
        }
    }
    
    interface Inter2 {
        public void print1();
        public void print2();
    }
    
    class Outer11 {
        public void method(){
            
            
            Inter2 p = new Inter2(){ //这个匿名内部类其实相当于一个实现了Inter2接口的子类匿名对象
                public void print1(){
                    System.out.println("print1");
                }
                
                public void print2(){
                    System.out.println("print2");
                }
                
                public void print3(){  //这个子类特有的方法没法使用
                    System.out.println("print3");
                }
            };
            
            p.print1();
            p.print2();
            //p.print3();//无法使用子类特有方法
            
            
        }
    }

匿名内部类在开发中的应用

  1. 用来传递参数
package test_heima;

//如何调用PersonDemo中的method方法
public class Test_Demo15 {
    public static void main(String[] args){
        //法1:使用多态
//        PersonDemo a = new PersonDemo();
//        a.method(new Student());
        
        //法2:使用匿名内部类
        PersonDemo a = new PersonDemo();
        a.method(new Person(){
            public void talk(){
                System.out.println("Hello1");
            }
        });
    }
}

abstract class Person {
    public void talk(){}
}

class PersonDemo {
    public void method(Person p){
        p.talk();
    }
}

//法1:使用多态
class Student extends Person {
    public void talk(){
        System.out.println("Hello");
    }
}

练习

  1. 这集视频值得再看一遍
package test_heima;

public class Test_Demo16 {
    public static void main(String[] args){
        Outer33.method().show();
    }
}

interface Inter33 {
    void show();
}

class Outer33 {
    //补齐代码
    public static Inter33 method(){ //返回Inter33接口的子类对象
        return new Inter33(){
            public void show(){
                System.out.println("HelloWorld");
            }
        };
    }
}

//控制台输出"HelloWorld"

Wall_Breaker
2.1k 声望1.2k 粉丝

生死之间,就是我的跃迁之路,全程记录,欢迎见证