形式参数
引用类型:
具体类:都需要创建该具体类对象
抽象类:如果方法的形式参数是抽象类类型,那么调用方法的实际参数需要传递该抽象类的子类对象
接口:如果方法的形式参数是接口类型,那么调用方法的实际参数需要改接口的子实现类对象.
1、具体类
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、抽象类
//抽象类特点:需要强制子类做的事情
abstract class Person{
//抽象功能
public abstract void love() ;
}
class PersonDemo{
public void function(Person p){//抽象类 不能实例化 必须通过抽象类多态的方式进行实例化
p.love() ;
}
}
//Scanenr sc = new Scanner(System.in) ;------>System.in--->InputStream
//传统方式
//定义一个抽象的子类(具体类)
class Student extends Person{
//必须重写功能
public void love(){
System.out.println("学生爱学习...") ;
}
}
//测试
class PersonTest{
public static void main(String[] args){
//需求:调用PersonDemo中的function方法()
PersonDemo pd = new PersonDemo() ;
//Person p = new Person() ; Person是抽象的; 无法实例化
//抽象类多态的方式
Person p = new Student() ;
pd.function(p);
}
}
3、接口
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、具体类
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() ;
}
}
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、接口类
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() ;
}
}
权限修饰符:
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
内部类可以访问外部类的成员,包括私有修饰的
//Outer是外部类
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 = 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:
静态的成员内部类只能访问外类的静态数据
静态的成员内部类要访问成员
格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
伪代码
有一个人,人有心脏(给当前人完成心脏搭桥手术)
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(); 不行了 ,如何访问
创建Body对象 Body b = new Body() ;
b.method() ;
//外部类
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 类名或者接口名(){
重写方法;
} ;
本质:
是一个继承了类或者实现了接口的子类匿名对象
Inter i = new Inter() ; 错误的
//定义一个接口
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() ;
}
}
看程序,写结果:
控制台输出 ,30,20,10
注意:
内部类中不存在继承关系,谈不上super
class Outer{
public int num = 10 ;
//成员内部类
class Inner{
//内部类的成员变量
int num = 20 ;
public void show(){
int num = 30 ;
System.out.println(num) ;
System.out.println(this.num) ;//访问的是本类(内部类)中的成员变量
//System.out.println(new Outer().num) ;//10-->外部类定义
//外部类的this限定
System.out.println(Outer.this.num) ;
}
}
}
//测试类
class OuterTest{
public static void main(String[] args){
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
匿名内部类在开发过程中的使用
new 类(具体类/抽象类)名或者接口名(){
};
abstract class Person{
public abstract void study();
}
class PersonDemo{
public void method(Person p ){ //方法的形参是抽象类类型
p.study() ;
}
}
//传统方式:定义出抽象类的子类
//方案:调用PersonDemo中的method方法()不能使用定义子类
class Student extends Person{
public void study(){
System.out.println("study Day Day Up") ;
}
}
class StudentTest{
public static void main(String[] args){
//调用PersonDemo中的method方法
PersonDemo pd = new PersonDemo();
//抽象类多态
Person p = new Student() ;
pd.method(p) ;
System.out.println("-------------") ;
//创建PersonDemo对象
PersonDemo pd2 = new PersonDemo() ;
//匿名内部类的应用场景
//针对移动端用的比较多,做PC端的开发
pd2.method(new Person(){
public void study(){
System.out.println("study Day Day Up") ;
}
}) ;
}
}
面试题:
要求在控制台输出”HelloWorld”
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()