一.多态的两种实现方式
- 1.使用父类作为方法形参实现多态:
当这个作为参数的父类是普通类或者抽象类时,构成继承多态;当这个父作为参数的父类是一个接口时,构成接口多态 - 2 使用父类作为方法返回值实现多态
(1).多态作为形参
形参为引入类型:普通类、抽象类、接口
1.普通类:当一个形参希望我们传入的是一个普通类时,我们实际上传入的是该类的对象/匿名对象
public class ArgsDemo01 {
public static void main(String[] args) {
// 需求: 访问StudentDemo中的method方法
//StudentDemo sd = new StudentDemo();
//利用匿名对象简化代码;
//new Student() {@Override
//public void study() {
// System.out.println("Student 子类 study");
//}
//}这是一个重写了方法的student的子类匿名对象
new StudentDemo().method(new Student() {
public void study() {
System.out.println("Student 子类 study");
}
});
}
}
class Student {
public void study() {
System.out.println("Student.study()");
}
}
class StudentDemo {
public void method(Student s) {
s.study();
}
}
2.抽象类:当一个形参希望我们传入的是一个抽象类时,我们实际上传入的是该类的子类对象/子类匿名对象
public class practice1 {
public static void main(String[] args) {
Person s= new students();
// 需求:访问tap
s.tap();
// 利用匿名对象简化
new students().tap();
// 重写Person的匿名子类对象.tap
new Person() {
public void tap() {
System.out.println("456");
}
}.tap();
// 需求:访问methods
Year sYear = new Year();
// 方法一:通过父类引用指向子类对象
sYear.methods(new students());
// new Person() {
// public void tap() {
// System.out.println("789");
// }
// }这是重写父类的匿名子类对象
sYear.methods(new Person() {
public void tap() {
System.out.println("789");
}
});
// 方式二:全部用匿名对象并添加功能
new Year().methods(new Person() {
public void tap() {
System.out.println("789");
System.out.println("456");
}
});
}
}
class Year{
public void methods(Person s) {
s.tap();
}
}
abstract class Person{
public abstract void tap();
}
class students extends Person{
public void tap() {
System.out.println("中国123");
}
}
3.接口:当一个形参希望我们传入的是一个接口时,我们实际上传入的是该类的实现类对象/实现类匿名对象
public class practice1 {
public static void main(String[] args) {
IPerson sIPerson= new studentsImpl();
// 访问tap
sIPerson.tap();
new studentsImpl().tap();
new IPerson() {
public void tap() {
System.out.println("456");
}
}.tap();
// 访问methods
Year sYear = new Year();
sYear.methods(new studentsImpl());
sYear.methods(new IPerson() {
public void tap() {
System.out.println("789");
}
});
new Year().methods(new IPerson() {
public void tap() {
System.out.println("789");
System.out.println("456");
}
});
}
}
class Year{
public void methods(IPerson s) {
s.tap();
}
}
interface IPerson{
public abstract void tap();
}
class studentsImpl implements IPerson{
public void tap() {
System.out.println("中国123");
}
}
(2).多态作为返回值
返回值类型:普通类、抽象类、接口
- 普通类
当一个方法的返回值是一个普通的类时,实际上返回的是该类的对象,我们可以使用该类的对象接收 - 抽象类
当一个方法的返回值是一个抽象类时,实际上返回的是该抽象类的子类对象,我们可以使用该抽象类接收 - 接口
当一个方法的返回值是一个接口时,实际上返回的是该接口的实现类对象,我们可以使用接口接收
二.内部类
-
1.内部类的概念:将类定义在类的内部,那么该类就成为内部类
注意: 内部类是一个相对的概念,如果A类中有一个B类,那么A类相对于B类来说就是外部类,那么B类相对于A类来说就是内部类 -
2.内部的分类
1.成员内部类
格式:
外部类类名.内部类类名 对象名 = 外部类对象.内部类对象
*/
public class InnerClassDemo03 {
public static void main(String[] args) {
//内部类命名
OuterClass3.InnerClass oi = new OuterClass3().new InnerClass();
oi.show();
oi.setNum2(100);
System.out.println(oi.getNum2());
}
}
class OuterClass3{
// 成员位置
private int num = 10;
//内部类
class InnerClass{
private int num2 = 20;
public void show() {
System.out.println(num);
System.out.println(num2);
}
public void setNum2(int num2) {
this.num2 = num2;
}
public int getNum2() {
return this.num2;
}
}
}
2.局部内部类
package com.sxt.innerclassdemo;
/*
* 局部内部类
*/
public class InnerClassDemo04 {
public static void main(String[] args) {
OuterClass4 outerClass4 = new OuterClass4();
outerClass4.show();
}
}
class OuterClass4{
class InnerClass{
}
public void show() {
int num = 50;
//局部内部类
class InnerClass{
private int num = 100;
public void method() {
System.out.println(num);
}
}
InnerClass innerClass = new InnerClass();
innerClass.method();
System.out.println(innerClass.num);
}
}
3.静态内部类
package com.sxt.innerclassdemo;
/*
* 静态内部类
* 成员内部类也可以使用static修饰
* 而且成员内部类还可以使用private的修饰
*
* 访问格式:
* 外部类类名.内部类类名 对象名 = new 外部类类名.内部类类名();
* 静态内部类主要成员是静态成员,可以方便调用,同时提高类的安全性
* 静态内部类可以有静态成员和非静态成员
*/
public class InnerClassDemo05 {
public static void main(String[] args) {
// OuterClass5.InnerClass oi = new OuterClass5.InnerClass();
// System.out.println(oi.num);
// oi.show();
// oi.show2();
System.out.println(OuterClass5.InnerClass.num2);
OuterClass5.InnerClass.show2();
}
}
class OuterClass5{
private int num = 5;
public static int num2 = 10;
public static class InnerClass{
public int num = 10;
public static int num2 = 20;
public void show() {
System.out.println("InnerClass.show()");
}
public static void show2() {
System.out.println("InnerClass.show2()");
}
}
public static void method() {
InnerClass innerClass = new InnerClass();
// System.out.println(num);
}
}
4.匿名内部类
package com.sxt.innerclassdemo;
/*
* 匿名内部类
* 概念:本质就是一个子类匿名对象
* 特点:
* 1.是一个子类
* 普通类
* 抽象类
* 接口
* 2.没有名字的子类
* 3.是一个对象
*
* 格式:
* new 类或者父类/抽象类/接口(){
* //重写方法;
* }
*
* 匿名内部类的本质一个继承(父类)或者实现(接口)的子类匿名对象
*/
public class InnerClassDemo07 {
public static void main(String[] args) {
new Student();
// 如果子类是普通类
// 匿名对象
new Student().show();
// 匿名子类对象
new Student() {}.show();
// 重写了show方法的匿名子类对象
new Student(){
public void show() {
System.out.println("Zi Student.show()");
}
}.show();
// 利用多态
AbsTeacher teacher = new PrimaryTeacher();
teacher.method();
// 匿名内部类 + 多态
// 这是一个继承并且重写method方法的AbsTeacher的子类匿名对象
new AbsTeacher() {
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("Zi PrimaryTeacher.method()");
}
}.method();
// 匿名内部类 + 多态
// 这是一个实现了Inter接口并且重写了method方法的子类匿名对象
new Inter() {
public void method() {
System.out.println("Inter impl");
};
}.method();
new IDemo() {
@Override
public void method() {
System.out.println("method impl");
}
@Override
public void method2() {
System.out.println("method2 impl");
}
}.method();
/*new IDemo() {
@Override
public void method() {
System.out.println("method impl");
}
@Override
public void method2() {
System.out.println("method2 impl");
}
}.method2();*/
System.out.println("------------------------------");
// 利用多态
IDemo iDemo = new IDemo() {
@Override
public void method() {
System.out.println("method impl");
}
@Override
public void method2() {
System.out.println("method2 impl");
}
};
iDemo.method();
iDemo.method2();
// 测试method方法
// ICar car = new CarImpl();
new CarDemo().method(new ICar() {
@Override
public void run() {
System.out.println("impl ICar2");
}
}).run();
}
}
class CarDemo{
// ICar c = new ICar() {
// @Override
// public void run() {
// System.out.println("impl ICar2");
// }
// }
public ICar method(ICar c) {
c.run();
// ICar car = new CarImpl();
return new ICar() {
@Override
public void run() {
System.out.println("impl Icar");
}
};
}
}
class CarImpl implements ICar{
@Override
public void run() {
System.out.println("CarImpl.run()");
}
}
interface ICar{
public void run();
}
interface IDemo{
void method();
void method2();
}
interface Inter{
void method();
}
abstract class AbsTeacher{
public abstract void method();
}
class PrimaryTeacher extends AbsTeacher{
@Override
public void method() {
System.out.println("Fu PrimaryTeacher.method()");
}
}
class Student{
public void show() {
System.out.println("Fu Student.show()");
}
}
经典题
/*
public class InnerClassDemo08 {
public static void main(String[] args) {
OuterClass8.Inner oi = new OuterClass8().new Inner();
oi.show();
}
}
class Fu{
public int num = 40;
public void show() {
int num = 50;
System.out.println(num);
}
}
class OuterClass8{
public int num = 10;
class Inner extends Fu{
public int num = 20;
public void show() {
int num = 30;
// 输出30
System.out.println(num);
// 输出20
System.out.println(this.num);
// 输出40
System.out.println(super.num);
// 输出50
super.show();
// 输出10
System.out.println(OuterClass8.this.num);
}
}
}