什么是多态?

概念:意味着允许不同类的对象对同一消息做出不同响应。

比如:按F1键,在eclipse中就会弹出 eclipse的帮助文档,在word中,就会弹出word帮助文档

在windows中就会弹出windows的帮助文档,这几个不同类的对象,在按下F1这个键会做出不同响应。

多态的必要条件 :

  1. -满足继承关系
  2. -父类引用指向子类对象(Animal two=new Cat();(向上转型、自动转型、隐式转型-由小到大转)子类的对象转型为一个父类的对象)

向上转型: 

也称:自动转型、隐式转型-由小到大转;

子类的对象转型为一个父类的对象Animal two=new Cat();

特点:可以调用子类重写父类的方法以及父类派生的方法,无法调用子类独有的方法

父类中的静态方法无法被子类重写,所以向上转型后,只能调用父类原有的静态方法

向下转型: 

也称强制类型转换(Cat temp=(Cat)two)

子类引用指向父类对象,此处必须进行强转,可以调用子类特有的方法

必须满足转型条件才能进行强转转换

 instanceof运算符:返回true、false

能用来判断左侧的对象是否满足右侧类型实例的特征

1-if( two instanceof Cat){}

2-if(two instanceof Animal)

3-if(two instance of Object)

返回都是true,1是右边Cat的实例,2,因为Cat的父类是Animal,3,Animal的最终类是Object

abstrast 关键字

抽象类:不允许实例化,但可以通过向上转型,指向子类实例(Animal one=new Cat();)

android 什么是多态_父类

抽象类和抽象方法的使用规则: 

  • 1.abstract定义抽象类
  • 2.抽象类不能直接被实例化,只能被继承,可以通过向上转型完成对象的实例 
  • 3.abstract定义抽象方法,不需要具体实现(public abstract eat();),并且子类都需要重写这个类
  • 4.包含抽象方法的类是抽象类
  • 5.抽象类中可以没有抽象方法
  • 6.static、final、private,不能喝abstract共存,static、final不能被重写,private只在当前类有效

抽象类的案例:

定义一个抽象类图像Shape类,由该派生出的两个子类圆Circle和矩形Rectangle类。

Shape里声明了抽象的area(),该方法分别再子类里得到实现。 

Shape.java

package com.demo.day6.polyProj;

public abstract class Shape {
	//无参构造方法
	public Shape() {
	}
	//定义一个area()的抽象方法
    public abstract void area();//不需要具体实现
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}

Circle.java

package com.demo.day6.polyProj;

public class Circle extends Shape {
    //私有属性
	private int r;
	
	public Circle(int r) {
		this.setR(r);
	}


	//重写Shape的area类
	@Override
	public void area() {
		//输出面积
		int r=this.getR();
		double area=Math.PI*r*r;
		System.out.println("圆的面积为:"+area);

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	public int getR() {
		return r;
	}

	public void setR(int r) {
		this.r = r;
	}
}

Rectangle.java

package com.demo.day6.polyProj;

public class Rectangle extends Shape {
	private int length;
	private int width;
	//带参构造函数
   public Rectangle(int length,int width) {
	   this.setLength(length);
	   this.setWidth(width);
   }
	@Override
	public void area() {
		// 输出长方形的面积
		double area=(this.getLength())*(this.getWidth());
		System.out.println("长方形的面积为:"+area);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	public int getLength() {
		return length;
	}
	public void setLength(int length) {
		this.length = length;
	}
	public int getWidth() {
		return width;
	}
	public void setWidth(int width) {
		this.width = width;
	}

}

ShapeTest.java

package com.demo.day6.test;

import com.demo.day6.polyProj.Circle;
import com.demo.day6.polyProj.Rectangle;
import com.demo.day6.polyProj.Shape;

public class ShapeTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
           Shape s=new Circle(4);
           s.area();
           Shape r=new Rectangle(3,4);//强转换
           r.area();
	}

}

输出结果:

圆的面积为:50.26548245743669
长方形的面积为:12.0

接口interface

 通过接口去描述不同的类型有相似的行为特征,(implements接口)从而建立关系之后,

以接口引用指向实现类来去描述不同的类型(接口类 接口引用=new  构造方法;)对于接口行为的具体表现

  • -接口定义了某一批类所需要遵守的规范
  • -接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类必须提供某些方法(接口里的方法)

接口成员:抽象方法&常量 

//接口访问修饰符:public默认
public interface INet{
        /*接口中抽象对象方法可以不写abstract关键字
         *访问修饰符默认public
         *当类实现接口时,需要去实现接口中所以得抽象方法,否则需要将该类设置为抽象类
         */
         public void network();
         public void connection();
     
         //接口中可以包含常量,默认public static final
         int TEMP=20;


}

 接口成员:默认方法&静态方法

package com.demo.day6.polyProj;

//接口访问修饰符:public默认
public interface INet{
      /*接口中抽象对象方法可以不写abstract关键字
       *访问修饰符默认public
       *当类实现接口时,需要去实现接口中所以得抽象方法,否则需要将该类设置为抽象类
       */
       public void network();
       public void connection();
   
       //接口中可以包含常量,默认public static final
       int TEMP=20;
       
       //default:默认方法 可以带方法体 jdk1.8后新增、用于某些类不必要的使用的方式
       //可以实现类中重写,并可以通过接口的引用调用
       default void connecttion() {
    	   System.out.println("我是默认方法");
       }
       
       //static:静态方法 可以带方法体 jdk1.8后新增
       //不可以在实现类中重写,可以在同接口名调用
       static void stop() {
    	   System.out.println("我是静态方法");
       }


}

关于多接口中重名默认方法处理的解决方案

如果一个子类继承之后实现多接口,

如果子类、父类、默认方法都有这个方法,会率先执行子类>父类>默认方法的的方法

接口继承:

接口也可以继承,可以继承多个接口 

接口案例:

 使用接口的知识,定义接口IFly,创建三个类Plane类、Bird类、Ballon类,分别重写接口中fly()方法,然后再测试类中进行调用。

IFly.java

package com.demo.day6.polyProj;

public interface IFly {
	//飞的方法
	void fly();
}

Plane.java

package com.demo.day6.polyProj;

public class Plane implements IFly{

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("飞机会飞");
	}

}

Bird.java

package com.demo.day6.polyProj;

public class Bird implements IFly{

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("小鸟会飞");
	}

}

Balloon.java

package com.demo.day6.polyProj;

public class Balloon implements IFly{

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("气球会飞");
	}

}

FlyTest.java

package com.demo.day6.test;

import com.demo.day6.polyProj.Balloon;
import com.demo.day6.polyProj.Bird;
import com.demo.day6.polyProj.Plane;

public class FlyTest {
    
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Bird one=new Bird();
		one.fly();
		Plane two=new Plane();
		two.fly();
		Balloon three=new Balloon();
		three.fly();

	}

}

输出结果:

小鸟会飞
飞机会飞
气球会飞

内部类

-在java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

成员内部类:

-与之对应,包含内部类的类被称为外部类

作用:内部类隐藏在外部类之内,更好的实现了信息的隐藏

分类:1、成员内部类 2、静态内部类 3、方法内部类 4、匿名内部类

-1成员内部类 

最常见的,也称普通内部类。

android 什么是多态_子类_02

内部类使用规则:

android 什么是多态_父类_03

-2静态内部类:

可以不依赖于外部类对象,直接创建

android 什么是多态_java_04

-3.方法内部类

 

android 什么是多态_java_05

-4.匿名内部类 

android 什么是多态_子类_06

综合案例:

BallTest.java

package com.demo.day6.polyProj;

public class BallTest implements Ball {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	// 匿名内部类调用的方法
	public void getBall(BallTest b) {
		b.play();
	}

	// 方法内部类
	public Object playBall() {
		class B implements Ball {

			@Override
			public String play() {

				return "方法内部类";
			}

		}
		return new B().play();// 通过构造函数调用play的方法

	}

	// 成员内部类
	public class Inner_m {
		public void play() {
			System.out.println("成员内部类");

		}

	}

	@Override
	public String play() {
		return null;
		// TODO Auto-generated method stub

	}

}

 Ball.java //接口

package com.demo.day6.polyProj;

public interface Ball {
  public String play();
}

Test1.java //测试

package com.demo.day6.test;

import com.demo.day6.polyProj.BallTest;

//测试Ball
public class Test1 {

	public static void main(String[] args) {
		// 完成成员内部类成员测试
		BallTest.Inner_m one = new BallTest().new Inner_m();
		one.play();
		// 完成方法内部类成员测试
		BallTest two = new BallTest();
		System.out.println(two.playBall());
		// 完成匿名内部类成员测试
		two.getBall(new BallTest() {

			public String play() {
				System.out.println("匿名内部类");
				return null;
			}
		});

	}
}

输出结果:

成员内部类
方法内部类
匿名内部类