链式编程,内部类"/>
java面向对象(三):形式参数和返回值,链式编程,内部类
1、形式参数和返回值
在学习java基础时,形式参数和返回值用的多是基本类型。但是当了学到面向对象后,形式参数和返回值涉及到类对象(非抽象类和接口)、抽象类对象和接口对象的形式了。
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()方法的返回值类型是一个接口。 */ } } |
发布评论