010-day10笔记--包,内部类
10.01_面向对象(package关键字的概述及作用)(了解)¶
- A:为什么要有包
-
将字节码(.class)进行分类存放
- 包其实就是文件夹
- B:包的概述
-
举例:
学生:增加,删除,修改,查询 老师:增加,删除,修改,查询 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 方案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 |
10.02_面向对象(包的定义及注意事项)(掌握)¶
-
A:定义包的格式
-
package 包名;
- 多级包用.分开即可
-
B:定义包的注意事项
-
A:package语句必须是程序的第一条可执行的代码
- B:package语句在一个java文件中只能有一个
- C:如果没有package,默认表示无包名
-
C:案例演示
-
包的定义及注意事项
```java /* * A:定义包的格式 * package 包名; * 多级包用.分开即可 * B:定义包的注意事项 * A:package语句必须是程序的第一条可执行的代码 * B:package语句在一个java文件中只能有一个 * C:如果没有package,默认表示无包名 / 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修饰的
1 2 3 4 5 6 7 8
/*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(); }
}
```
```java package com.baidu; //百度的包 public class Person { //Person类 带包的类 private String name; private int age;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
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"); }
}
```
```java package com.xxx; import com.baidu.Person; public class Student extends Person { public Student(){}
1 2 3 4 5 6 7
public Student(String name,int age) { super(name,age); } public void method() { print(); }
}
```
10.03_面向对象(带包的类编译和运行)(掌握)¶
-
A:如何编译运行带包的类
-
a:javac编译的时候带上-d即可(这样就会自动的将类放到我们制定的文件路径中com.heima)
-
javac -d . HelloWorld.java 注意 . 的后面要有一个空格
M:\java视频\01.第一阶段\day10\code\1_包>javac -d . Demo1_Package.java
-
b:通过java命令执行。
-
java 包名.HellWord
M:\java视频\01.第一阶段\day10\code\1_包>java com.heima.Demo1_Package
注意不要带后缀执行结果:
java 张三...23 李四...24 print
-
10.04_面向对象(不同包下类之间的访问)(掌握)¶
-
A:案例演示
-
不同包下类之间的访问
10.05_面向对象(import关键字的概述和使用)(掌握)¶
-
A:案例演示
-
为什么要有import
-
其实就是让有包的类对调用者可见,不用写全类名了
```java /* * A:定义包的格式 * package 包名; * 多级包用.分开即可 * B:定义包的注意事项 * A:package语句必须是程序的第一条可执行的代码 * B:package语句在一个java文件中只能有一个 * C:如果没有package,默认表示无包名 / 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修饰的
1 2 3 4 5 6 7 8
/*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(); }
}
```
-
-
B:导包格式
-
import 包名; (导包导的是类)
- 注意:
- 这种方式导入是到类的名称。
- 虽然可以最后写*,但是不建议。(会降低效率在开发中都是导入具体的类)
-
C:package,import,class有没有顺序关系(面试题)
10.06_面向对象(四种权限修饰符的测试)(掌握)¶
-
A:案例演示
-
四种权限修饰符
- B:结论 :测试还是用的前面的例子
-
bash 本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类) private Y 默认 Y Y protected Y Y Y public Y Y Y Y
10.07_面向对象(类及其组成所使用的常见修饰符)(掌握)¶
- A:修饰符:
- 权限修饰符:private,默认的,protected(受保护的),public
- 状态修饰符:static,final
- 抽象修饰符:abstract
- B:类:
-
权限修饰符:默认修饰符,public #外部类不能使用private 和 protected
- 状态修饰符: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
10.08_面向对象(内部类概述和访问特点)(了解)¶
-
A:内部类概述
-
B:内部类访问特点
-
a:内部类可以直接访问外部类的成员,包括私有。
- b:外部类要访问内部类的成员,必须创建对象。
- 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
-
C:案例演示
-
内部类极其访问特点
```java class Demo1_InnerClass { public static void main(String[] args) { //Inner i = new Inner(); //i.method(); //外部类名.内部类名 = 外部类对象.内部类对象 Outer.Inner oi = new Outer().new Inner(); //创建内部类对象 oi.method();
1
}
}
/* * A:内部类概述 * B:内部类访问特点 * a:内部类可以直接访问外部类的成员,包括私有。 * b:外部类要访问内部类的成员,必须创建对象。 * 外部类名.内部类名 对象名 = 外部类对象.内部类对象; * C:案例演示 * 内部类极其访问特点 */
class Outer { //外部类 private int num = 10; class Inner { //内部类 public void method() { System.out.println(num); //内部类可以访问外部类的私有属性,跟python一样的 } } }
```
10.09_面向对象(成员内部类私有使用)(了解)¶
- private
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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(); } } |
10.10_面向对象(静态成员内部类)(了解)¶
-
static
-
B:成员内部类被静态修饰后的访问方式是:
-
外部类名.内部类名 对象名 = 外部类名.内部类对象;
```java class Demo1_InnerClass { public static void main(String[] args) { //外部类名.内部类名 对象名 = 外部类名.内部类对象; Outer.Inner oi = new Outer.Inner(); oi.method();
1 2
Outer.Inner2.print(); //静态类中的静态方法一路点进行调用 }
}
class Outer { static class Inner { public void method() { System.out.println("method"); } }
1 2 3 4 5
static class Inner2 { public static void print() { System.out.println("print"); } }
} ```
10.11_面向对象(成员内部类的面试题)(掌握)¶
- A:面试题
-
1
要求:使用已知的变量,在控制台输出30,20,10。
```java class Test1_InnerClass { public static void main(String[] args) { Outer.Inner oi = new Outer().new Inner(); oi.show(); } } //要求:使用已知的变量,在控制台输出30,20,10。 //内部类之所以能获取到外部类的成员,是因为他能获取到外部类的引用外部类名.this 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); //使用this调用本类的成员变量 System.out.println(Outer.this.num); //外部类名+this 进行调用外部类的变量 } } }
```
10.12_面向对象(局部内部类访问局部变量的问题)(掌握)¶
-
A:案例演示
-
局部内部类访问局部变量必须用final修饰
-
局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么? 因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用
但是jdk1.8取消了这个事情,所以我认为这是个bug
```java 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); //内部类中调用num必须要常量 } }1 2 3 4 5 6 7 8
Inner i = new Inner(); //在方法内创建内部类的对象 i.print(); } /*public void run() { Inner i = new Inner(); //局部内部类,只能在其所在的方法中访问 i.print(); }*/
} ```
-
10.13_面向对象(匿名内部类的格式和理解)¶
-
A:匿名内部类
-
就是内部类的简化写法。
-
B:前提:存在一个类或者接口
-
这里的类可以是具体类也可以是抽象类。
-
C:格式:
-
1 2 3
new 类名或者接口名(){ 重写方法; }
-
D:本质是什么呢?
-
是一个继承了该类或者实现了该接口的子类匿名对象。
-
E:案例演示
-
按照要求来一个匿名内部类
```java class Demo1_NoNameInnerClass { public static void main(String[] args) { Outer o = new Outer(); o.method(); } } /* * A:匿名内部类 * 就是内部类的简化写法。 * B:前提:存在一个类或者接口 * 这里的类可以是具体类也可以是抽象类。 * C:格式: * new 类名或者接口名(){ 重写方法; } * D:本质是什么呢? * 是一个继承了该类或者实现了该接口的子类匿名对象。 * E:案例演示 * 按照要求来一个匿名内部类 */
interface Inter { public void print(); }
class Outer { class Inner implements Inter { public void print() { System.out.println("print"); } }
1 2 3 4 5 6 7 8 9 10 11 12
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(); //print前面的东西整个代表inter的子类对象使用.print调用print方法 }
} ```
10.14_面向对象(匿名内部类重写多个方法调用)¶
-
A:案例演示
-
匿名内部类的方法调用
```java 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"); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
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(); //匿名内部类是不能向下转型的,因为没有子类类名 }
} ```
10.15_面向对象(匿名内部类在开发中的应用)¶
-
A:代码如下
-
//这里写抽象类,接口都行
1 2 3
abstract class Person { public abstract void show(); }
```java class PersonDemo { public void method(Person p) { p.show(); } }
class PersonTest { public static void main(String[] args) { //如何调用PersonDemo中的method方法呢? PersonDemo pd = new PersonDemo ();
1
}
}
java 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 {
1 2 3 4 5 6 7 8 9 10 11
//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"); } } ```
10.16_面向对象(匿名内部类的面试题)¶
-
A:面试题
-
按照要求,补齐代码
java interface Inter { void show(); } class Outer { //补齐代码 } class OuterDemo { public static void main(String[] args) { Outer.method().show(); } } 要求在控制台输出”HelloWorld”
```java 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” ```