包
包的概述
其实就是文件夹
作用:对类进行分类管理
包的划分:
举例:
学生的增加,删除,修改,查询
老师的增加,删除,修改,查询
以及以后可能出现的其他的类的增加,删除,修改,查询
基本的划分:按照模块和功能分。
/*
包:
A:其实就是文件夹
B:作用
a:把相同的类名放到不同的包中
b:对类进行分类管理
举例:
学生:增加,删除,修改,查询
老师:增加,删除,修改,查询
...
方案1:按照功能分
com.it18zhang..add
AddStudent
AddTeacher
com.it18zhang..delete
DeleteStudent
DeleteTeacher
com.it18zhang..update
UpdateStudent
UpdateTeacher
com.it18zhang..find
FindStudent
FindTeacher
方案2:按照模块分
com.it18zhang..teacher
AddTeacher
DeleteTeacher
UpdateTeacher
FindTeacher
com.it18zhang..student
AddStudent
DeleteStudent
UpdateStudent
FindStudent
包的定义
package 包名;
多级包用.分开即可
注意事项:
A:package语句必须是程序的第一条可执行的代码
B:package语句在一个java文件中只能有一个
C:如果没有package,默认表示无包名
带包的编译和运行:
A:手动式
a:编写一个带包的java文件。
b:通过javac命令编译该java文件。
c:手动创建包名。
d:把b步骤的class文件放到c步骤的最底层包
e:回到和包根目录在同一目录的地方,然后运行
带包运行。
B:自动式
a:编写一个带包的java文件。
b:javac编译的时候带上-d即可
javac -d . HelloWorld.java
c:回到和包根目录在同一目录的地方,然后运行
带包运行。
*/
package com.it18zhang;
class HelloWorld {
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
包的定义及注意事项
定义包的格式
package 包名;
多级包用.分开即可
注意事项:
package语句必须是程序的第一条可执行的代码
package语句在一个java文件中只能有一个
如果没有package,默认表示无包名
带包的类的编译和运行
手动式
a:javac编译当前类文件。
b:手动建立包对应的文件夹。
c:把a步骤的class文件放到b步骤的最终文件夹下。
d:通过java命令执行。注意了:需要带包名称的执行
java com.it18zhang.HelloWorld
自动式
a:javac编译的时候带上-d即可
javac -d . HelloWorld.java
b:通过java命令执行。和手动式一样
不同包下类之间的访问
定义两个类:Demo,Test。
Demo
求和方法(sum)
Test
测试方法(main)
/*
Test类,测试
导包:
格式:import包名;
这种方式导入是到类的名称。
注意:我们用谁就导谁。
面试题:
package,import,class有没有顺序关系?
有。
package > import > class
Package:只能有一个
import:可以有多个
class:可以有多个,以后建议是一个
*/
package cn.it18zhang;
import com.zhang.Demo;
class Test {
public static void main(String[] args) {
//Demo d = new Demo();
/*
com.zhang.Demo d = new com.zhang.Demo();
System.out.println(d.sum(10,20));
com.zhang.Demo d2 = new com.zhang.Demo();
System.out.println(d2.sum(10,20));
com.zhang.Demo d3 = new com.zhang.Demo();
System.out.println(d3.sum(10,20));
com.zhang.Demo d4 = new com.zhang.Demo();
System.out.println(d4.sum(10,20));
*/
Demo d = new Demo();
System.out.println(d.sum(10,20));
}
}
/*
第一个问题:找不到Demo
第二个问题:程序包com.zhang不存在
第三个问题: Demo在com.zhang中不是公共的;无法从外部程序包中对其进行访问
*/
/*
Demo类,求和
*/
package com.zhang;
public class Demo {
public int sum(int a,int b) {
return a + b;
}
}
导包
不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能。
导包格式
import 包名;
注意:
这种方式导入是到类的名称。
虽然可以最后写*,但是不建议。
package,import,class有没有顺序关系(面试题)
权限问题
/*
权限修饰符:
本类同一个包下(子类和无关类)不同包下(子类)不同包下(无关类)
private Y
默认 YY
protectedYYY
publicYYYY
*/
package com.zhang;
public class Father {
private void show() {
System.out.println("show");
}
void show2() {
System.out.println("show2");
}
protected void show3() {
System.out.println("show3");
}
public void show4() {
System.out.println("show4");
}
public static void main(String[] args) {
Father f = new Father();
f.show();
f.show2();
f.show3();
f.show4();
}
}
package com.zhang;
public class Sonextends Father {
public static void main(String[] args) {
Father f = new Father();
//f.show();
f.show2();
f.show3();
f.show4();
System.out.println("--------------");
Son s = new Son();
//s.show();
s.show2();
s.show3();
s.show4();
}
}
package com.zhang;
public class Test {
public static void main(String[] args) {
Father f = new Father();
//f.show();
f.show2();
f.show3();
f.show4();
}
}
不同包
package cn.qx;
import com.zhang.Father;
public class Son2extends Father {
public static void main(String[] args) {
Father f = new Father();
//f.show();
//f.show2();
//f.show3();
f.show4();
System.out.println("--------------");
Son2 s = new Son2();
//s.show();
//s.show2();
s.show3();
s.show4();
}
}
package cn.qx;
import com.zhang.Father;
class Test2 {
public static void main(String[] args) {
Father f = new Father();
//f.show();
//f.show2();
//f.show3();
f.show4();
}
}
类及其组成可以用的修饰符
类:
默认,public,final,abstract
我们自己定义:public居多
成员变量:
四种权限修饰符均可,final,static
我们自己定义:private居多
构造方法:
四种权限修饰符均可,其他不可
我们自己定义:public 居多
成员方法:
四种权限修饰符均可,fianl,static,abstract
我们自己定义:public居多
/*
修饰符:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
类:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多的就是:public
成员变量:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
用的最多的就是:private
构造方法:
权限修饰符:private,默认的,protected,public
用的最多的就是:public
成员方法:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
用的最多的就是:public
除此以外的组合规则:
成员变量:public static final
成员方法:public static
public abstract
public final
*/
//此处不允许使用修饰符private
//此处不允许使用修饰符protected
//此处不允许使用修饰符static
public class Demo {
//成员变量
private int x = 10;
int y = 20;
protected int z = 30;
public int a = 40;
public final int b = 50;
public static int c = 60;
public static final int d = 70;
//此处不允许使用修饰符abstract
//abstract int e = 80;
//构造方法
private Demo(){}
Demo(String name){}
protected Demo(String name,int age) {}
public Demo(String name,int age,String address) {}
//此处不允许使用修饰符static
//public static Demo(){}
//此处不允许使用修饰符final
//public final Demo() {}
//此处不允许使用修饰符abstract
//public abstract Demo(){}
//成员方法
//static void show() {}
//abstract void show();
//final void show(){}
}
内部类概述
把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
内部类的访问特点:
内部类可以直接访问外部类的成员,包括私有。
外部类要访问内部类的成员,必须创建对象。
/*
内部类概述:
把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
内部的访问特点:
A:内部类可以直接访问外部类的成员,包括私有。
B:外部类要访问内部类的成员,必须创建对象。
*/
class Outer {
private int num = 10;
class Inner {
public void show() {
System.out.println(num);
}
}
public void method() {
//找不到符号
//show();
Inner i = new Inner();
i.show();
}
}
class InnerClassDemo {
public static void main(String[] args) {
}
}
内部类位置
按照内部类在类中定义的位置不同,可以分为如下两种格式:
成员位置(成员内部类)
局部位置(局部内部类)
/*
内部类位置
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。
成员位置:在成员位置定义的类,被称为成员内部类。
*/
class Outer {
private int num = 10;
//成员位置
/*
class Inner {
}
*/
public void method() {
//局部位置
class Inner {
}
}
}
class InnerClassDemo2 {
public static void main(String[] args) {
}
}
外界如何创建对象
外部类名.内部类名 对象名= 外部类对象.内部类对象;
/*
成员内部类:
如何直接访问内部类的成员。
外部类名.内部类名 对象名= 外部类对象.内部类对象;
*/
class Outer {
private int num = 10;
class Inner {
public void show() {
System.out.println(num);
}
}
}
class InnerClassDemo3 {
public static void main(String[] args) {
//需求:我要访问Inner类的show()方法
//Inner i = new Inner();
//i.show();
//格式:外部类名.内部类名 对象名= 外部类对象.内部类对象;
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
成员内部类
刚才我们讲解过了,成员内部类的使用,但是一般来说,在实际开发中是不会这样使用的。因为一般内部类就是不让外界直接访问的。
举例讲解这个问题:Body和Heart,电脑和CPU。
成员内部的常见修饰符
private 为了保证数据的安全性
static 为了让数据访问更方便
被静态修饰的成员内部类只能访问外部类的静态成员
内部类被静态修饰后的方法
静态方法
非静态方法
/*
成员内部类的修饰符:
private 为了保证数据的安全性
static 为了方便访问数据
注意:静态内部类访问的外部类数据必须用静态修饰。
案例:我有一个人(人有身体,身体内有心脏。)
class Body {
private class Heart {
public void operator() {
System.out.println("心脏搭桥");
}
}
public void method() {
if(如果你是外科医生) {
Heart h = new Heart();
h.operator();
}
}
}
按照我们刚才的讲解,来使用一下
Body.Heart bh = new Body().new Heart();
bh.operator();
//加了private后,就不能被访问了,那么,怎么玩呢?
Body b = new Body();
b.method();
*/
class Outer {
private int num = 10;
private static int num2 = 100;
//内部类用静态修饰是因为内部类可以看出是外部类的成员
public static class Inner {
public void show() {
//System.out.println(num);
System.out.println(num2);
}
public static void show2() {
//System.out.println(num);
System.out.println(num2);
}
}
}
class InnerClassDemo4 {
public static void main(String[] args) {
//使用内部类
// 限定的新静态类
//Outer.Inner oi = new Outer().new Inner();
//oi.show();
//oi.show2();
//成员内部类被静态修饰后的访问方式是:
//格式:外部类名.内部类名 对象名= new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
oi.show2();
//show2()的另一种调用方式
Outer.Inner.show2();
}
}
局部内部类
可以直接访问外部类的成员
可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
局部内部类访问局部变量的注意事项:
必须被final修饰?
为什么呢?
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值。通过反编译工具可以看一下
/*
局部内部类
A:可以直接访问外部类的成员
B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
面试题:
局部内部类访问局部变量的注意事项?
A:局部内部类访问局部变量必须用final修饰
B:为什么呢?
局部变量是随着方法的调用而调用,随着调用完毕而消失。
而堆内存的内容并不会立即消失。所以,我们加final修饰。
加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
我在内存中存储的是数据20,所以,我还是有数据在使用。
*/
class Outer {
private int num = 10;
public void method() {
//int num2 = 20;
//final int num2 = 20;
class Inner {
public void show() {
System.out.println(num);
//从内部类中访问本地变量num2;需要被声明为最终类型
System.out.println(num2);//20
}
}
//System.out.println(num2);
Inner i = new Inner();
i.show();
}
}
class InnerClassDemo5 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
匿名内部类
就是内部类的简化写法。
前提:存在一个类或者接口
这里的类可以是具体类也可以是抽象类。
格式:
new 类名或者接口名() {重写方法;}
本质:
是一个继承了类或者实现了接口的子类匿名对象
/*
匿名内部类
就是内部类的简化写法。
前提:存在一个类或者接口
这里的类可以是具体类也可以是抽象类。
格式:
new 类名或者接口名(){
重写方法;
}
本质是什么呢?
是一个继承了该类或者实现了该接口的子类匿名对象。
*/
interface Inter {
public abstract void show();
public abstract void show2();
}
class Outer {
public void method() {
//一个方法的时候
/*
new Inter() {
public void show() {
System.out.println("show");
}
}.show();
*/
//二个方法的时候
/*
new Inter() {
public void show() {
System.out.println("show");
}
public void show2() {
System.out.println("show2");
}
}.show();
new Inter() {
public void show() {
System.out.println("show");
}
public void show2() {
System.out.println("show2");
}
}.show2();
*/
//如果我是很多个方法,就很麻烦了
//那么,我们有没有改进的方案呢?
Inter i = new Inter() {//多态
public void show() {
System.out.println("show");
}
public void show2() {
System.out.println("show2");
}
};
i.show();
i.show2();
}
}
class InnerClassDemo6 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
匿名内部类的应用
/*
匿名内部类在开发中的使用
*/
interface Person {
public abstract void study();
}
class PersonDemo {
//接口名作为形式参数
//其实这里需要的不是接口,而是该接口的实现类的对象
public void method(Person p) {
p.study();
}
}
//实现类
class Student implements Person {
public void study() {
System.out.println("好好学习,天天向上");
}
}
class InnerClassTest2 {
public static void main(String[] args) {
//测试
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
System.out.println("--------------------");
//匿名内部类在开发中的使用
//匿名内部类的本质是继承类或者实现了接口的子类匿名对象
pd.method(new Person(){
public void study() {
System.out.println("好好学习,天天向上");
}
});
}
}