package关键字
为什么要有包?
将字节码(.class)进行分类存放
包其实就是文件夹
包的定义及注意事项
定义包的格式
package 包名
多级包用.分割,如package com.heima里面的.就是分隔符
定义包的注意事项
- package语句必须是程序的第一条可执行的代码
- package语句在一个Java文件中只能有一个
- 如果没有package默认表示无包名
cmd如何编译运行带包的类
- javac编译的时候带上-d即可,例如javac -d.HelloWorld.java
- 通过java命令执行,java 包名.HelloWorld
不同包下类之间的访问
import关键字
为什么会有import?
其实就是让有包的类对调用者可见,不用写全类名了
导包格式:
- import包名
- 这种方式导入是到类的名称,最后可以写*通配符但是不建议
package语句子啊java文件中第一个
import在中间
class在package和import下面
没有导包前每次访问其他类都需要写包名
导包后不用在写包名
*通配符
权限修饰符
结论:
protected
面向对象—类及其组成所使用的常见修饰符
修饰符
- 权限修饰符:private,默认的(default),protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
类
- 权限修饰符:默认的(default),public(用的最多)
- 状态修饰符:final
- 抽象修饰符:abstract
成员变量
- 权限修饰符:private(用的最多),默认的,protected,public
- 状态修饰符:static,final
构造方法
- 权限修饰符:private,默认的,protected,public(用的最多)
成员方法
- 权限修饰符:private,默认的,protected,public(用的最多)
- 状态修饰符:static,final
- 抽象修饰符:abstract
组合规则
- 成员变量:public static final(接口成员变量)
- 成员方法:
1、public static;
2、public final;
3、public abstract
内部类概述和访问特点
内部类概述:被定义为在另一个类中声明的类
内部类的访问特点:1、内部类可以直接访问外部类的成员,包括私有;2、外部类访问内部类成员必须向创建类,格式为:外部类名.内部类名 对象名 = 外部类对象.内部类对象
练习代码
public class InnerClass {
public static void main(String[] agrs) {
//创建内部类对象,外部类访问内部类的成员必须创建对象,格式为:外部类名.内部类名 对象名 = 外部类对象.内部类对象
out.inner oi = new out().new inner();
oi.print();
}
}
class out {
private int num = 15;
class inner {
public void print() {
System.out.println(num);//内部类直接访问外部类成员变量,包括私有
}
}
}
输出结果:
成员内部类的私有使用
练习代码
public class InnerClass {
public static void main(String[] agrs) {
//创建内部类对象,外部类访问内部类的成员必须创建对象,格式为:外部类名.内部类名 对象名 = 外部类对象.内部类对象
//out.inner oi = new out().new inner();
//oi.print();无法访问私有的方法
//实例化out类,然后访问类中的方法
out o = new out();
o.print();
}
}
class out {
private int num = 15;
class inner {
private void print() {
System.out.println(num);//内部类直接访问外部类成员变量,包括私有
}
}
//在本类创建一个public公用方法来访问本类的private方法
public void print() {
out.inner oi = new out().new inner();
oi.print();
}
}
运行结果
静态成员内部类
访问静态内部类的格式:外部类名.内部类名 对象名 = 外部类名.内部类对象
练习代码
public class StaticClass {
public static void main(String[] agrs) {
//访问静态内部类的格式:外部类名.内部类名 对象名 = 外部类名.内部类对象
Outer.Inner OI = new Outer.Inner();
OI.methed();
//访问静态内部类中静态方法
Outer.Inner1.methed1();
}
}
class Outer {
static class Inner { //静态内部类
public void methed() {
System.out.println("静态内部类的输出");
}
}
static class Inner1 {
public static void methed1() {
System.out.println("静态内部类+静态方法的输出");
}
}
}
内部类之所以能获取到外部类的成员,是因为他能获取到外部类的引用,外部类名.this
局部内部类访问局部变量
局部内部类访问局部变量必须用final修饰
原因:因为当调用这个方法时,局部变量如果没有final修饰,他的生命周期和方法的生命周期一样,当方法弹栈,局部变量消失,如果局部内部类对象还没有马上消失,想用这个变量就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在也可以继续使用,但是jdk1.8取消了这个规则,感觉是bug
练习代码
package com.Demo08;
public class Demo08_InnerTest {
public static void main(String[] agrs) {
Outerr o = new Outerr();
o.Outmethed();
}
}
class Outerr {
public void Outmethed() {
final int n = 20;//局部内部类访问局部变量必须用final修饰
class inner {
public void Innermethed() {
System.out.println("hello");
System.out.println(n);
}
}
inner i = new inner();
i.Innermethed();
}
}
运行结果
匿名内部类的格式和理解
匿名内部类就是内部类的简化写法
前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类
格式:new 类名或者接口名(){重写方法}
本质上是一个继承了该类或者实现了该接口的子类匿名对象
练习代码
package com.Demo08;
public class Demo08_nonameclass {
public static void main(String[] agrs) {
name name = new name();
name.mehted();
}
}
interface inter {
public void print();
}
class name {
class name1 implements inter { //有名字的内部类
public void print() {
System.out.println("有名字的内部类");
}
}
public void mehted() {
name1 n = new name1();
n.print();
//inter的子对象 new inter是实现inter
new name1().print();
new inter() { //实现了inter接口
public void print() { //重写了抽象方法
System.out.println("匿名内部类");
}
}.print();//后面的print相当于执行方法
}
}
运行结果
匿名内部类重写多个方法调用
匿名内部类只针对重写一个方法时候使用
匿名内部类不能向下转型
练习代码
public class Demo08_nonameclass {
public static void main(String[] agrs) {
name name = new name();
name.mehted();
}
}
interface inter {
public void print1();
public void print2();
}
class name {
class name1 implements inter { //有名字的内部类
public void print1() {
System.out.println("有名字的内部类1");
}
public void print2() {
System.out.println("有名字的内部类2");
}
}
public void mehted() {
name1 n = new name1();
n.print1();
n.print2();
//inter的子对象 new inter是实现inter
// new name1().print1();
inter i = new inter() { //实现了inter接口
public void print1() { //重写了抽象方法1
System.out.println("匿名内部类1");
}
public void print2() { //重写了抽象方法2
System.out.println("匿名内部类2");
}
};//.print();//后面的print相当于执行方法
i.print1();
i.print2();
}
}
运行结果
匿名内部类在开发中的应用
练习代码
public class NoNameClassTest {
public static void main(String[] agrs) {
persondemo pd = new persondemo();
pd.method(new student() { //匿名内部类当作参数传递(本质把匿名内部类看作一个对象)
public void show() {
System.out.println("匿名内部类在开发中的应用 1");
}
});
}
}
abstract class person {
public abstract void show();
}
class persondemo {
public void method(person p) { //person p = new student();
p.show();
}
}
class student extends person {
public void show() {
System.out.println("匿名内部类在开发中的应用");
}
}
运行结果