一:多态
- 接口的多种不同实现方式为多态
- 实现 多态的前提:1,有继承或者接口(实现)的关系 2,要有覆盖
- 多态在代码中的体现:父类或者接口的引用指向子类的对象
- 多态的好处:提高了代码的扩展性,前期定义的代码可以使用后期的内容
- 多态的弊端:前期定义的内容不能调用后期子类特有的内容
instanceof:用于判断对象的局域类型,只能用于引用数据的类型判断
if(a instanceof Cat)//通常在向下转型时用于健壮
{}
else if(a instanceof Dog)
{}
class YeYe{
void speak(){
System.out.println("teach English");
}
void activite(){
System.out.println("fish fish");
}
}
class Me extends YeYe{
void speak(){
System.out.println("teach java ");
}
void watch(){
System.out.println("watch movies");
}
}
class PolymorphicDemo2{
public static void main(String [] args){
YeYe y=new Me();
y.speak();
y.activite();
//y.watch();
}
}
二:举例说明多态性
- 动物的多态性
- 对象的多态性
class 动物{}
class 猫 extends 动物{}
class 狗 extends 动物{}
猫 x =new 猫();
动物 x=new 动物();
动物 x =new 猫();一个对象。两种形态(左右两种形态)
animal a=new cat();
自动类型提升(----向上转型),猫对象提升了动物的类型,但是特有功能无法访问
作用:限制对特有功能的访问
如果还想具体动物猫的特有功能,可以将该功能进行向下转型—为了使用子类中特有的方法
Cat c=(Caat)a;
c.eat();
c.catchMouse();
注意:对于转型,自始至终都是子类对象在做着类型的变化
猫这类事物即具备猫的形态,又具备动物的形态
这就是对象的多态—某一类事物的多种存在形态
简单来说:就是一个对象对应着不同类型、
abstract class Animal{
abstract void eat();
}
class Dog extends Animal{
void eat(){
System.out.println("kengutou ");
}
void kanJia(){
System.out.println("kanjia ");
}
}
class Cat extends Animal{
void eat(){
System.out.println("chilaoshu");
}
void work(){
System.out.println("zhualaoshu ");
}
}
class Pig extends Animal{
void eat(){
System.out.println("chiyecai");
}
}
class PolymorphicDemo{
public static void main(String [] args){
Dog d=new Dog();
//d.eat();
Cat c=new Cat();
//c.eat();
method (c);
method(d);
method(new Pig());
}
public static void method(Animal a){//Animal a=new Dog();
a.eat();
}
}
三:多态时,成员的特点
1,成员变量
编译时:参考引用型变量所属类中的是否有调用的成员变量,有-编译通过,没有-编译失败
运行时:参考引用型变量所属类中的是否有调用的成员变量,并运行该所属类中的成员变量
简单来说:编译和运行都参考左边(=的左边)
class Fu{
int num=4;
}
class Zi extends Fu{
int num=3;
}
class Demo{
public static void main(String[] args){
Fu f=new Zi();//向上转型,将之类型隐藏,就不用使用子类的特有方法
f.num();
}
}
2,成员函数(非静态)
编译时:参考引用型变量所属类中的是否有调用的成员变量,有-编译通过,没有-编译失败
Fu f=new Zi();//向上转型,将之类型隐藏,就不用使用子类的特有方法
运行时:参考 的是对象所属的类是否有调用的函数
简单说:编译看左边,运行看右边
3,静态函数
编译时:参考引用型变量所属类中的是否有调用的静态方法
运行时:参考引用型变量所属类中的是否有调用的静态方法
简单来说:编译和运行都参考左边
其实静态方法不需要对象,直接用类名调用
class Fu {
void show(){
System.out.println("fu fu show");
}
static void method(){
System.out.println("fu static method");
}
}
class Zi extends Fu{
void show(){
System.out.println("zi zi show ");
}
static void method(){
System.out.println("zi static method");
}
}
class PolymorphicDemo3{
public static void main(String [] args){
Fu f=new Zi();
f.show();
f.method();
Fu.method();
Zi.method();
}
}
四:内部类
- 将一个类定义在另一个类或者方法里面,就是内部类
- 内部类的特点
-内部类可以直接访问外部类
-外部类要先在内部类建立对象才可以访问内部类
五:关于内部类的设计
1,一把用于类的设计:
分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容---------这时就是还有的事物定义成内部类来描述
2,
//直接访问外部类中的内部类
Outer.Inner in=new Outer().new Inner();
in.show();
//如果内部是静态的,相当于一个外部类
Outer.Inner in=new Outer.Inner();
in.show();
//如果内部是静态的,成员是静态的
Outer.Inner.function();
, 静态不能定义在内部类中
class Outer{
private static int num=44;
static class Inner{
private int num=5;
void show (){
System.out.println("show run....."+num);
}
static void function (){
System.out.println("function run show");
}
}
public void method(){
Inner in=new Inner();
in.show();
}
}
class InnerClassDemo{
public static void main(String[] args){
//Outer o=new Outer();
//o.method();
Outer.Inner in=new Outer().new Inner();
in.show();
//Outer.Inner in=new Outer.Inner();
//in.show();
Outer.Inner.function();
}
}
3,为什么内部类能都直接访问外部类中的成员?
-因为内部类持有 外部类的引用---------外部类.this
class Outer{
int num=3;
class Inner{
int num=4;
void show(){
int num=5;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
void method(){
new Inner().show();
}
}
class InnerClassDemo2{
public static void main(String[] args){
new Outer().method();
}
}
4,内部类可以存放 在局部位置上
.----内部类在局部位置上只能访问局部中被final修饰的局部变量
class Outer{
int num=3;
void method(){
final int x=9;
class Inner{
void show(){
System.out.println("show......"+num);
System.out.println("show......"+x);
}
}
Inner in=new Inner();
in.show();
}
}
class InnerClassDemo3{
public static void main(String[] args){
new Outer().method();
}
}
六:匿名内部类
-
匿名内部类:简写内部类的格式
-
匿名内部类的前提:内部类必须继承或者实现一个外部类或者接口
-
匿名内部类就是一个匿名子子类
–格式:new 父类or接口名{}子类名称 -
通常使用场景之一:
-当函数参数是接口类型时,而且接口中的方法呢不超过三个
-可以用匿名内部类作为实际参数进行传递
abstract class Demo{
abstract void show();
}
class Outer{
int num=4;
/*class Inner extends Demo{
void show(){
System.out.println("shwo------------"+num);
}
}*/
public void method(){
//new Inner().show();
new Demo(){//nimingneibulei
void show(){
System.out.println("show....."+num);
}
}.show();
}
}
class InnerClassDemo4{
public static void main(String[] args){
new Outer().method();
}
}
interface Inter{
void show1();
void show2();
}
class Outer{
/*class Inner implements Inter{
public void show1(){}
public void show2(){}
}*/
public void method(){
/*Innner in=new Inner();
in.show1();
in.show2();
System.out.println();*/
Inter in=new Inter(){
public void show1(){}
public void show2(){}
};
in.show1();
in.show2();
}
}
class InnerClassDemo5{
public static void main(String[] args){
//new Outer().method();
show (new Inter(){
public void show1(){}
public void show2(){}
});
}
public static void show(Inter in){
in.show1();
in.show2();
}
}