【172天】黑马程序员27天视频学习笔记【Day10】
叨逼叨两句
- 我勒个去,不要小看这一天的内容啊,真特么多,看来我Java继承还真挺一般的,还要继续努力!
- 明天复习这10天内容。
10-(01-05):package与import
package关键字概述及作用
- 就是文件夹
- 按功能划分或者按模块划分
- 增删改查
包的定义及注意事项
- package语句在java文件中只能有一个
- 如果没有package,默认表示没有包名
- package语句必须是程序的第一条可执行代码
- 该视频值得在看一遍
带包的类编译和运行
- 用javac编译test.java应该这样:
javac -d . test.java
这样编译后生成的class文件路径将是com/heima/test.class
。 -
.
代表当前目录,这里也可以改成别的目录。 - 要运行这样一个文件,需要在创建这个包的目录打开命令行运行`java
com.heima.test`
package com.heima;
public class test {
}
- 该视频值得在看一遍
import关键字的概述和使用
- 作用:让那些带包的类,对调用其的类可见
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;
}
}
-
*
通配符开发一般不用,因为它需要检索,挨个匹配,降低效率。
10-(06-07)
权限修饰符权限说明
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认(default) Y Y
protected Y Y Y
public Y Y Y Y
修饰符使用一览
修饰符类别
- 权限修饰符:private、default、protected、public
- 状态修饰符:static、final
- 抽象修饰符:abstract
类
- 权限修饰符:default、public(常用)
- 状态修饰符:final
- 抽象修饰符:abstract
成员变量
- 权限修饰符:private(常用)、default、protected、public
- 状态修饰符:static、final
- 抽象修饰符:无
成员方法
- 权限修饰符:private、default、protected、public
- 状态修饰符:static、final
- 抽象修饰符:abstract
构造方法
- 权限修饰符:private、default、protected、public
- 状态修饰符:无
- 抽象修饰符:无
其它组合规则
- 成员变量:public static final
-
成员方法:
- public static
- public abstract
- public final
- abstract和final、static、private不可同时使用
10-(08-16)内部类
内部类概述及访问特点
- 内部类可以直接访问外部类的成员,包括私有
-
外部类要访问内部类的成员,必须创建对象。
外部类.内部类 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);
}
}
}
局部内部类里面的方法调用方式
- 局部内部类开发用的很少
-
局部内部类里面的方法调用方式
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(); } }
局部内部类访问局部变量的方式
- 在JDK1.7中,局部内部类访问他所在的方法中的局部变量时,需要加上final修饰符。但是JDK1.8中不需要了,估计是个bug。
- 局部内部类访问他所在的方法中的局部变量必须用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();
}
}
匿名内部类的使用格式和理解
- 匿名内部类是内部类的简化写法
- 匿名内部类是局部内部类的一种,必须写在方法里。
- 前提:存在一个类(方便匿名内部类继承,这个类可以是具体类,也可以是抽象类)或者接口(方便匿名内部类实现)
-
格式:
new 类名或者接口名(){ 重写方法; }
- 本质:一个继承成了该类或者实现了该接口的子类匿名对象。
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();
}
}
匿名内部类重写多个方法的情况
-
匿名内部类适用于一次性使用,多次调用建议使用有名的内部类。
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(); } }
-
可以将父类引用指向子类对象,但是,由于匿名对象没类名,无法实现向下转型,所以无法使用子类特有的方法。
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();//无法使用子类特有方法 } }
匿名内部类在开发中的应用
- 用来传递参数
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");
}
}
练习
- 这集视频值得再看一遍
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"
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。