什么是多态?
概念:意味着允许不同类的对象对同一消息做出不同响应。
比如:按F1键,在eclipse中就会弹出 eclipse的帮助文档,在word中,就会弹出word帮助文档
在windows中就会弹出windows的帮助文档,这几个不同类的对象,在按下F1这个键会做出不同响应。
多态的必要条件 :
- -满足继承关系
- -父类引用指向子类对象(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();)
抽象类和抽象方法的使用规则:
- 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成员内部类
最常见的,也称普通内部类。
内部类使用规则:
-2静态内部类:
可以不依赖于外部类对象,直接创建
-3.方法内部类
-4.匿名内部类
综合案例:
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;
}
});
}
}
输出结果:
成员内部类
方法内部类
匿名内部类