1、形式参数和返回值

类对象(非抽象类和接口)、抽象类对象和接口对象的形式了。

  1.1、当形式参数和返回值为类对象

形式参数为类对象

返回值为类对象

class Student {
     public void show() {
         System.out.println("我爱学习");
     }
 }class StudentDemo {
     //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
     public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
         s.show();
     }
 }class Test {
     public static void main(String[] args) {
         //形式参数是引用类型的调用
         //需求:我要调用StudentDemo类中的method()方法
         StudentDemo sd = new StudentDemo();
         //创建学生对象
         Student s = new Student();
         sd.method(s); //把s的地址给到了这里
     }
 }
class Student {
     public void show() {
         System.out.println("我爱学习");
     }
 }class StudentDemo {
     public Student getStudent() {  //声明返回值类型为类
         return new Student();  //返回值参数为该类的对象
     }
 }class Test {
     public static void main(String[] args) {
         StudentDemo sd = new StudentDemo();    
         Student s = new Student();//调用getStudent()
         s.show();; //调用Student类的show()
     }
 }

       1.2、当形式参数和返回值为抽象类对象

形式参数为抽象类对象

返回值为抽象类对象

abstract class Person {
     public abstract void study();
 }class PersonDemo {
     public void method(Person p) {//p; p = new Student();  Person p = new Student(); //多态
         p.study();
     }
 }//定义一个具体的学生类
 class Student extends Person {
     public void study() {
         System.out.println("Good Good Study,Day Day Up");
     }
 }class TestDemo {
     public static void main(String[] args) {
         //需求:我要使用PersonDemo类中的method()方法
         //因为抽象类不能实例化的,但我们可以通过多态定义一个具体类去实现
         PersonDemo pd = new PersonDemo();
         Person p = new Student();
         pd.method(p); //通过多态实现
     }
 }//传形参是多态实现的抽象类子类对象
abstract class Person {
     public abstract void study();
 }class PersonDemo {
     public Person getPerson() {
         //Person p = new Student();
         //return p;
         
         return new Student();
     }
 }class Student extends Person {
     public void study() {
         System.out.println("Good Good Study,Day Day Up");
     }
 }class TestDemo {
     public static void main(String[] args) {
         //需求:我要测试Person类中的study()方法
         PersonDemo pd = new PersonDemo();
         Person p = pd.getPerson(); //new Student();  Person p = new Student(); 多态
         p.study();
     }
 }

  1.3、当形式参数和返回值为接口对象

形式参数为接口对象

返回值为接口对象

//定义一个爱好的接口
 interface Hobby {
     public abstract void hobby();
 }class HobbyDemo {
     public void method(Hobby h) { //h; h = new Teacher();  Hobby h = new Teacher(); 多态
         h.hobby();
     }
 }//定义具体类实现接口
 class Teacher implements Hobby {
     public void hobby() {
         System.out.println("老师爱学生,爱Java,爱坂井泉水");
     }
 }class TestDemo {
     public static void main(String[] args) {
         //需求:我要测试LoveDemo类中的love()方法
         HobbyDemo hd = new HobbyDemo();
         Hobby h = new Teacher();
         hd.method(h);
     }
 }
interface Hobby {
     public abstract void hobby();
 }class HobbyDemo {
     public Hobby getLove() {
         //Hobby h = new Teacher();
         //return h;
         
         return new Teacher();
     }
 }//定义具体类实现接口
 class Teacher implements Hobby {
     public void hobby() {
         System.out.println("老师爱学生,爱Java,爱坂井泉水");
     }
 }class TestDemo {
     public static void main(String[] args) {
         //如何测试呢?
         HobbyDemo hd = new HobbyDemo();
         Hobby h = hd.getLove(); //new Teacher(); Love l = new Teacher(); 多态
         h.hobby();
     }
 }

2、链式编程

       在java面向对象中,每次进行类的实例化Student s = sd.getStudent()后,还需要通过类的引用进行方法的调用s.study()。

       链式编程:可经过n次方法的调用,在第n次方法调用前返回都是对象;在第n次时,返回的可以不是对象

两个经典的链式编程

//案例1
class Student {
     public void study() {
         System.out.println("Good Good Study,Day Day Up");
     }
 }class StudentDemo {
     public Student getStudent() {
         return new Student();
     }
 }class TestDemo {
     public static void main(String[] args) {
         //如何调用的呢?
         StudentDemo sd = new StudentDemo();
         //Student s = sd.getStudent();
         //s.study();
         
         //大家注意了
         sd.getStudent().study();
     }
 }
//执行结果如下
Good Good Study,Day Day Up
//案例2
class Student {
     //姓名
     private String name;
     //年龄
     private int age;
     
     //姓名获取值
     public String getName() {
         return name;
     }
     
     //姓名设置值
     public Student setName(String n) { 
         this.name = n;
        return this;  //设置对象name值并返回对象的引用
     }
     
     //年龄获取值
     public int getAge() {
         return age;
     }
     
     //年龄赋值
     public Student setAge(int a) {
         this.age = a;
         return this; //设置对象age值并返回对象的引用
     }
 }class TestDemo {
     public static void main(String[] args) {
         //创建学生对象
         Student s1 = new Student().setAge(18).setName("坂井泉水");
         System.out.println(s1.getName()+"的年龄是"+s1.getAge()+"岁");
     }
 }//执行结果如下
坂井泉水的年龄是18岁

3、内部类

       在java中,在一个类A里定义了一个类B,那么B是A的内部类。java的内部类分为成员内部类局部内部类匿名内部类

  3.1、成员内部类和局部内部类

内部类位置
        成员位置:在成员位置定义的类,被称为成员内部类。    
        局部位置:在局部位置定义的类,被称为局部内部类。

    内部的访问特点:
        A:内部类可以直接访问外部类的成员,包括私有。
        B:外部类要访问内部类的成员,必须创建对象。

class Outer {
     private int num = 10;    //成员位置
     
     class Inner { //成员内部类
         
     }
         public void method() {        
         class Inner { //局部内部类
         
         }
     }
 }class InnerClassDemo2 {
     public static void main(String[] args) {
         
     }
 }

  3.2、成员内部类两种访问方式

访问(无static修饰的)成员内部类的成员:

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();
     }
 }

访问static修饰的成员内部类的成员:

class Outer {
     private int num = 10;
     private static int num2 = 200;
     
     //内部类用静态修饰是因为内部类可以看出是外部类的成员
     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) {        
         //成员内部类被静态修饰后的访问方式是:
         //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
         Outer.Inner oi = new Outer.Inner();
         oi.show();
         oi.show2();
         
         //show2()的另一种调用方式,因为static修饰的类成员可以通过类名调用
         Outer.Inner.show2();
     }
 }

  3.3、局部内部类的访问方式

局部内部类:

        A:可以直接访问外部类的成员

        B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能

class Outer {
     private int num  = 10;
     
     public void method() {
         int num2 = 20;
         //final int num2 = 20;  //在jdk1.8前局部内部类访问的局部变量要用final修饰
         class Inner {
             public void show() {
                 System.out.println(num);
                 //从内部类中访问本地变量num2; 需要被声明为最终类型
                 System.out.println(num2);//20
             }
         }
         
         Inner i = new Inner(); //在局部位置,创建内部类对象来调用内部类方法使用局部内部类功能
         i.show();
     }
 }class InnerClassDemo5 {
     public static void main(String[] args) {
         Outer o = new Outer();
         o.method();
     }
 }

  3.4、匿名内部类

       匿名内部类就是内部类的简化写法,本质是一个继承了该类或者实现了该接口的子类匿名对工象,而且是适合一次使用的类。 这里的类可以是具体类也可以是抽象类、接口

匿名内部类的格式:

    格式:

        new 类名或者接口名(){

            重写方法;

        }

//匿名内部类案例1:
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();
     }
 }

  3.5、三道经典的匿名内部类案例

1、匿名内部类在开发中的使用

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("好好学习,天天向上");
             }
         });
     }
 }

2、匿名内部类面试1:

/*
     面试题:
         要求请填空分别输出30,20,10。
         
     注意:
         1:内部类和外部类没有继承关系。
         2:通过外部类名限定this对象
             Outer.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);
             //System.out.println(new Outer().num);
             System.out.println(Outer.this.num);
         }
     }
 }
 class InnerClassTest {
     public static void main(String[] args) {
         Outer.Inner oi = new Outer().new Inner();
         oi.show();
     }    
 }

3、匿名内部类面试2:

/*
     匿名内部类面试题:
         按照要求,补齐代码
             interface Inter { void show(); }
             class Outer { //补齐代码 }
             class OuterDemo {
                 public static void main(String[] args) {
                       Outer.method().show();
                   }
             }
             要求在控制台输出”HelloWorld”
 */
 interface Inter { 
     void show(); 
     //public abstract
 }class Outer { 
     //补齐代码
     public static Inter method() {
         //子类对象 -- 子类匿名对象
         return new Inter() {
             public void show() {
                 System.out.println("HelloWorld");
             }
         };
     }
 }class OuterDemo {
     public static void main(String[] args) {
         Outer.method().show();
         /*
             1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
             2:Outer.method().show()可以看出method()方法的返回值是一个对象。
                 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
         */
     }
 }