Day12
形式参数是引用类型的深入研究
引用类型:
具体类:都需要创建该具体类对象
抽象类:如果方法的形式参数是抽象类类型,那么调用方法的实际参数需要改抽象类的子类对象
接口:如果方法的形式参数是接口类型,那么调用方法的实际参数需要改接口的子实现类对象.
1.形式参数如果是一个具体的类,需要该类对象 Student s = new Student();
class Student{
public void study(){
System.out.println("好好学习,天天向上") ;
}
}
class StudentDemo{
public void method(Student s){ //形式参数如果是一个具体的类,需要该类对象 Student s = new Student();
s.study() ;
}
}
//测试
class StudentTest{
public static void main(String[] args){
//需求:调用StudentDemo中的method 方法
//创建StudentDemo类对象
StudentDemo sd = new StudentDemo() ;
//创建Student对象
Student student = new Student() ;
sd.method(student) ;
System.out.println("--------------") ;
//匿名对象
new StudentDemo().method(new Student()) ;
}
}
2.形式参数是接口类型 ,方法调用时需要传递的是该接口的子实现类对象
interface Love{
//抽象方法
void love() ; //默认修饰符
}
class TeacherDemo{
public void show(Love l){//形式参数是接口类型 ,方法调用时需要传递的是该接口的子实现类对象
l.love() ;
}
}
//传统方式:定义一个接口的子实现类
class Teacher implements Love{
public void love(){
System.out.println("老师爱生活,爱高圆圆...") ;
}
}
//测试
class TeacherTest{
public static void main(String[] args){
//需求:调用TeacherDemo类中的show方法
TeacherDemo td = new TeacherDemo();
//Love love = new Love() ;接口不能实例化
//td.show(love) ;
//改进:接口多态
Love love = new Teacher() ;
td.show(love) ;
}
}
返回值是引用类型研究
基本类型: 四类八种 public int sum(int a,int b){} 返回什么类型,就是使用当前基本类型接收数据即可!
引用类型:
具体类:如果方法的返回值类型是具体类,需要返回的是该类的具体对象
抽象类:如果方法的返回值是一个抽象类类型,需要返回的是该抽象类的子类对象
接口:如果方法的返回值是一个接口类型,需要返回该接口的子实现类对象!
1.返回值是接口类型,不能直接返回接口,需要返回的是该接口的子实现类对象
//接口
interface Train{
public abstract void study() ;
}
class TeacherDemo{
public Train method(){ //返回值是接口类型,不能直接返回接口,需要返回的是该接口的子实现类对象
//返回值 return
//return new Train(); 接口不能实例化
//分步走
//接口多态
//Train tr = new TrainImpl() ;
//return tr ;
return new TrainImpl() ;
}
}
//定义接口的子实现类
class TrainImpl implements Train{
public void study(){
System.out.println("学习JavaEE...") ;
}
}
class InterfaceTest{
public static void main(String[] args){
//需求:调用TeacherDemo中的method方法
TeacherDemo td = new TeacherDemo() ;
Train t = td.method() ;//返回值是接口类型 Train t = new TrainImpl() ;
t.study() ;
}
}
2.返回值是一个抽象类,需要通过子类进行实例化
//抽象类
abstract class Person{
public abstract void work() ;
}
class PersonDemo{
public Person function(){//返回值是一个抽象类,需要通过子类进行实例化
//需要返回值 return
//return new Person() ; //不能实例化
//抽象类多态
//分步走
//Person p = new Student() ; //抽象类多态
//return p ;
return new Student() ;
}
}
//传统方式:定义一个抽象类的子类
class Student extends Person{
public void work() {
System.out.println("学生喜欢敲代码...");
}
}
class PersonTest{
public static void main(String[] args){
//需求:调用PersonDemo中的function方法
//创建PersonDemo对象
PersonDemo pd = new PersonDemo() ;
Person p = pd.function() ; //返回抽象类Person对象 Person p = new Student() ;
p.work();
//Scanner sc = new Scanner(System.in) ;System.in---->返回值是InputStream:抽象类
}
}
3.返回值类型是具体类,需要返回的是该类的具体对象
class Student{
public void study(){
System.out.println("Good Good Study,Day Day Up") ;
}
}
class StudentDemo{
public Student method(){ //如果返回值类型是具体类,需要返回的是该类的具体对象
//分步走
//Student s = new Student() ;
//return s ;
//return ;
return new Student() ;//匿名对象
}
}
//测试:
class StudentTest{
public static void main(String[] args){
//需求:调用StudentDemo中method 方法
StudentDemo sd = new StudentDemo() ;
//调用
Student s = sd.method() ;
s.study() ;
}
}
包的概念
包: 见名知意!
其实文件夹
多级包:
com.qianfeng.zhangsan
com
qianfeng
zhangsan
== 作用==:就是为了分类管理类
一个java中,一般情况就定义一个类
包的关键字:package 导包的关键字:import 定义类class
位置在class的上面
位置顺序:
package > import >class
分类管理类的意义:为了后期修改代码方便或者提高结构维护性
实际操作:增删改查
按照功能划分
com.qianfeng.add;
addStudent() ;
addTeacher() ;
com.qianfeng.delete;
deleteStudent();
deleteTeacher();
com.qianfeng.update;
updateStudent();
updateTeacher();
com.qianfeng.find;
findStudent();
findTeacher();
按照模块划分:
com.qianfeng.student;
add();
delete();
update();
find();
com.qianfeng.teacher;
add();
delete();
update();
find();
在同一个包下:
手动方式:麻烦
1.编写好java文件,java文件中携带pacakge 包名;
2.使用javac将java源文件进行编译,---->类名.class 字节码文件
3.在当前目录下创建对应的包名
4.将class文件放入到对应包中
5.java 包名.类名
自动方式
1.javac编译的时候带上-d即可(java -d . 源文件----->包会自动生成)
javac -d . HelloWorld.java
b:通过java命令执行。和手动式一样
java 包名.类名
修饰符
权限修饰符:
public ,private ,默认,protected(受保护的)
状态修饰符
static,final
抽象:abstract
权限修饰符:public
private:对于一般标准类中的成员变量private使用居多,对于工具类(通用代码,无参构造方法被private修饰)
默认修饰符: 在使用在同一个包下(使用记事本编辑 默认是最多)
protected:(不同包下,子类的修饰符中见的多(Javaweb—>Servlet))
状态修饰符一般和public结合使用最多
public static
public static final (定义常量并且被类名调用)
默认修饰符 static final
抽象abstract和哪些关键字冲突 public abstract(对方法进行抽象)/public abstract class(抽象类)
private
static
final
static:一般情况 (成员方法中居多)—>Math类中的功能,StringBuffer中的append(),
成员变量中使用多(定义常量: public static final)
内部类
内部类概念:
在一个类中定义一个类
在类B中定义A类,或者类A中定义一个类B
内部类可以访问外部类的成员,包括私有修饰的
class Outer{
//外部类的成员变量
private int num = 10 ;
//内部类
class Inter{
//成员方法
public void show(){
System.out.println(num) ;
}
}
//在外部类的成员位置,访问内部类的成员,必须创建内部类对象
public void method(){
//show() ; //错误
Inter i = new Inter() ; //创建内部类对象
i.show();
}
}
class OuterDemo{
public static void main(String[] args){
//创建外部类对象
Outer o = new Outer() ;
o.method() ;
}
}
内部类的分类
成员内部类:在类中的成员位置
局部内部类:在方法的局部位置
class Outer{
private int num = 100 ;
//成员位置
//成员内部类
class Inter{
}
//Outer的成员方法
public void method(){
//局部内部类
class Inter2{
}
}
}
class OuterDemo2{
public static void main(String[] args){
}
}
成员内部类==(非静态)==的访问特点:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
//定义外部类
class Outer{
private int num = 20 ;
//成员内部类
class Inter{
public void show(){
System.out.println("show inter...") ;
}
}
}
//测试
class OuterDemo3{
public static void main(String[] args){
//需求:访问外部类中的内部类的成员
//Inter i = new Inter() ; Inter i = new Inter() ;
//i.show() ;
//外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer.Inter oi = new Outer().new Inter() ;
oi.show() ;
}
}
成员内部类的修饰符:
- 可以被private修饰,保证数据的安全性!
static:
2.静态的成员内部类只能访问外类的静态数据
静态的成员内部类要访问成员
格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名()
//外部类
class Outer{
public int num = 10 ;
public static int num2 = 30 ;
//有静态的成员内部类
public static class Inter{ //成员内部类被静态修饰,可以看成是外部类的一个成员
public void show(){
//System.out.println(num) ; //无法从静态上下文中引用非静态 变量 num
System.out.println(num2) ;
}
public static void show2(){
//System.out.println(num) ;//无法从静态上下文中引用非静态 变量 num
System.out.println(num2) ;
}
}
}
//测试
class OuterDemo4{
public static void main(String[] args){
//外部类名.内部类名 对象名 = 外部类对象.内部类对象;
//Outer.Inter oi = new Outer().new Inter() ;//限定的新静态类 不适合静态的成员内部类
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inter oi = new Outer.Inter() ;
oi.show();
oi.show2();
System.out.println("------------") ;
//show2()的访问方式:属于Inter的静态成员 Inter.show2();
//将Inter整体看成是外部类的成员(static修饰了)
//链式编程格式
Outer.Inter.show2();
}
}
局部内部类:
1.可以访问外部类成员,包括私有
2.在外部类局部位置可以去访问局部内部类成员,创建该内部类对象,使用对象访问
Jdk1.7以前,包含1.7,局部内部类访问局部变量,局部变量必须使用final修饰
通过反编译工具---->将.class文件 进行优化
当前局部内部类访问局部变量,在内存中已经被优化
final int val$num2;
面试题:
为什么在内存使用final修饰?(jdk1.8处理掉了编译错误)
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还
要使用那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实
是一个常量值(jdk1.8不用,底层原码已经优化了!)
class Outer{
private int num = 10 ;
//成员方法
public void method(){
//局部变量
int num2 = 50 ;
//局部内部类
class Inner{ //内存中 可能要被new 类名()
public void show(){
System.out.println(num) ;//10
System.out.println(num2) ;
}
}
Inner i = new Inner();
i.show() ;
}
}
//测试
class OuterDemo5{
public static void main(String[] args){
//创建外部类对象
Outer o = new Outer();
o.method() ;
}
}
匿名内部类
前提条件:
存在一个类或者接口
类:可以具体类,可以是抽象类
格式:
new 类名或者接口名( ){
重写方法;
} ;
本质:
是一个继承了类或者实现了接口的子类匿名对象
//定义一个接口
interface Inter{
public abstract void show() ;
public abstract void show2() ;
}
class Outer{
//成员方法
public void method(){
//使用匿名内部类的方式实现接口中的show(){}
/*
new 类名或者接口名(){
重写方法;
}
*/
//整个部分:new 接口名(){重写方法} ; 就是一个子实现类对象
//接口中只有一个抽象方法
/*
new Inter(){
public void show() {
System.out.println("show Inter...") ;
}
}.show() ;
*/
//如果接口中的有多个抽象方法
/*
new Inter(){
public void show() {
System.out.println("show Inter...") ;
}
public void show2() {
System.out.println("show Inter...") ;
}
}.show();
new Inter(){
public void show() {
System.out.println("show Inter...") ;
}
public void show2() {
System.out.println("show2 Inter...") ;
}
}.show2();
*/
//直接使用对象名调用多个抽象
Inter i = new Inter(){
public void show(){
System.out.println("show Inter...") ;
}
public void show2() {
System.out.println("show2 Inter...") ;
}
};
//调用
i.show();
i.show2();
}
}
//测试
class OuterDemo6{
public static void main(String[] args){
Outer o = new Outer() ;
o.method() ;
}
}
匿名内部类的实际开发空间
new 类(具体类/抽象类)名或者接口名(){
};
interface Inter {
void show();
}
class Outer {
//补齐代码
public static Inter method(){//返回值类型是引用类型(接口)
//匿名内部类
/*
格式:
new 类名或者接口名{
重写抽象方法;
};
*/
return new Inter(){
public void show(){
System.out.println("HelloWorld") ;
}
};
}
}
//测试类
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
/*
Outer.method()------->用类调用方法----->method方法是静态方法 public static 返回值类型 method()
Outer.method(). show(); Outer.method()能够调用show(),说明前面部分可以返回一个对象,并且该对象能访问接口中的
show( )
*/