Hello 大家好,讲完了类与对象的两大基本特征,本文就让我们一起进入面向对象的第三大特征——多态,感受多态所带来的魅力
所谓向上,用一句话来讲就是【父类引用指向子类对象】,对于上转型对象,它可以说是多态的雏形,要学好多态必须先了解上转型对象。好,废话不所说,直接上代码
public class Animal {
String name;
public Animal(String name) {
this.name = name;
}
void eat(){
System.out.println(this.name + "正在吃东西");
}
}
public class Cat extends Animal{
public Cat(String name) {
super(name);
}
@Override
void eat() {
System.out.println(this.name + "正在吃鱼");
}
}
public class test {
public static void main(String[] args) {
Animal animal = new Cat("咪咪");
animal.eat();
}
}
接下去我们来了解一下产生上转型对象的三种方式,可以可以帮我们在实例开发中快速的判断自己是否在使用上转型对象
这种的话就是我上面作为引入的案例
Animal animal = new Cat("咪咪");
animal.eat();
从下面的代码可以看出,是将一个本类方法的形参设置为父类的引用,然后将子类的对象作为实参传入,这也可以形成上转型对象
public static void func(Animal animal){
animal.eat();
}
public static void main(String[] args) {
Cat cat = new Cat("咪咪");
func(cat);
}
这种方式比较抽象而且难理解,因为是采用父类这个类型作为返回值,因为直接new一个子类的对象去返回,就自然地形成了上转型对象,这个确实不太好理解,大家要自己观察一下,就不给代码,给的指示图片
说完了三种上转型对象的方式,接下去我们说说使用在这个上转型对象时我们需要注意哪些
Animal animal;
Cat c = animal;
好,最后我们再来说一下上转型对象和接口回调的区别,接口的话会在下一篇文章讲【implements关键字】的时候讲到,这里先提一嘴
讲到了多态,也不能忘了继承,接下去就让我们来讲讲继承和多态之间的联系,以及它们都有哪些优点
然后来看一个小案例
class Animal{
void cry(){
}
}
class Dog extens Animal{
void cry(){
System.out.println("汪汪~~");
}
}
class Cat extens Animal{
void cry(){
System.out.println("喵喵~~");
}
}
class test{
public static void main(String[] args) {
Animal animal;
animal = new Dog();
animal.cry();
animal = new Cat();
animal.cry();
}
}
了解了多态的基本概念之后,我们要接下来说说要如何去实现多态
清楚了如何产生多态的条件,那我们就要去想,这个多态究竟有什么好处呢,为什么她是面向对象中最终要的一趴,接下来我们来说说这个
class Geometry{
void draw(){
System.out.println("画一个几何图形");
}
}
class Circle extends Geometry{
@Override
void draw() {
System.out.println("画一个⚪");
}
}
class Slice extends Geometry{
@Override
void draw() {
System.out.println("画一个♦");
}
}
class Triangle extends Geometry{
@Override
void draw() {
System.out.println("画一个▲");
}
}
public class test2 {
public static void main(String[] args) {
Circle circle = new Circle();
Slice slice = new Slice();
Triangle triangle = new Triangle();
String[] shapes = {"cycle","triangle","slice","cycle"};
for(String shape : shapes)
{
if(shape.equals("cycle")){
circle.draw();
}else if(shape.equals("triangle")){
triangle.draw();
}else if(shape.equals("slice")){
slice.draw();
}
}
}
}
OK,是时候展现真正的技术了
Geometry[] shapes = {new Circle(),new Triangle(),new Slice(),new Circle()};
for(Geometry shape : shapes){
shape.draw();
}
对,就是这么简便,我们可以直接在这个对象数组中放new出来的子类对象,然后在遍历这个数组的时候便发生了上转型对象,利用父类的引用shape去调用每一次传入进来的子类对象,就可以去独立地方法那个子类所重写的方法,这就很好地体现了多态的思想
③对于最后这一点,还是比较好理解的,就是可扩展能力强【无限地增加继承的子类】
比如说你要加一个正方形类,只需要把这个类实现一下然后去继承一下Geometry父类即可,完全不需要改动任何的代码,这就是多态的优势之处
看完了上面这些,那您就算初步地了解了多态这个概念,但是并没有形成那个思维,只是一个引入,接下来我们便通过abstract这个关键字真正地进入多态的编程模式,感受面向抽象的编程思维
class Geometry{
void draw(){
System.out.println("画一个几何图形");
}
}
abstract void draw();
那这时候就有同学说,哇,这个关键字很厉害、很高级的感觉。是的,不然我不会前面铺垫那么多,才讲到这个关键字,厉害归厉害,但是在使用这个关键字的时候要注意的地方还是挺多的,让我们一起来看一下
为什么不能被实例化呢?都说了它是抽象的嘛,怎么能会有一个具体的东西呈现给你呢,是吧所以下面这步操作你不可以做
Geometry shape = new Geometry();
此话怎讲呢?也就是这个抽象类,它除了不能对抽象方法做实现外,其他其实也和普通的类没什么区别,普通的成员变量和成员方法都是可以定义的
abstract class Geometry{
private int num;
public void func(){
System.out.println("这是抽象类的一个实例方法");
}
abstract void draw();
}
这个的话就要理解,因为抽象类的话已经不可以被实例化对象了,那你再不能继承它然后做一些操作的话,那这个类不就没用了吗,是吧,然后这个抽象方法的话,你在抽象类中没有重写它,在继承子类中也没有对其进行一个重写,也是很荒谬的一件事,上一篇文章中我们有详细讲过final关键字,说到了final这个关键字如果去修饰方法的时候,那么这个方法就不可以被重写,如果去修饰类的话,那么这个类就不可以被继承,所以大家一定不要把abstract和final关键字写在一起,这是矛盾的
这个的话在上面也讲到过了,如果一个类去继承了一个抽象类,那么你就必须重写其中的抽象方法,否则的话要么你自己也定成一个抽象类,然后继承你的子类就必须要重写你父类的方法,就如下面的代码一样
abstract class ff extends Geometry{
}
class gg extends ff{
@Override
void draw() {
}
}
因为static关键字指的是静态方法,是可以被所有同包下的类所调用的,然后其他类就可以重写这个方法自己用,这就违背了继承的特性,只有子类才可以重写父类的方法
然后的话priavate关键字因为是私有的,那子类就是无法访问的,私有的成员变量还可以通过get()方法来访问一下,如果父类的方法都私有化了,那么子类是无法去访问的
讲了这么多有关abstract关键字的注意事项,现在就让我们到实战中来看看它是具体怎么应用的吧
女朋友类(doge)
public abstract class GirlFriend {
abstract void speak();
abstract void cooking();
}
中国女朋友类(doge)
public class ChinaGirlFriend extends GirlFriend{
@Override
void speak() {
System.out.println("你好");
}
@Override
void cooking() {
System.out.println("会做水煮鱼");
}
}
美国女朋友类(doge)
public class AmericanGiralFriend extends GirlFriend{
@Override
void speak() {
System.out.println("Hello");
}
@Override
void cooking() {
System.out.println("Can make roast beef");
}
}
男孩类
public class Boy {
GirlFriend girlFriend;
void setGirlFriend(GirlFriend f){
girlFriend = f;
}
void showGirlFriend(){
girlFriend.speak();
girlFriend.cooking();
}
}
测试类
public class test {
public static void main(String[] args) {
GirlFriend girlFriend = new ChinaGirlFriend();
Boy boy = new Boy();
System.out.println("中国女朋友");
boy.setGirlFriend(girlFriend);
boy.showGirlFriend();
girlFriend = new AmericanGiralFriend();
System.out.println("--------------");
System.out.println("美国女朋友");
boy.setGirlFriend(girlFriend);
boy.showGirlFriend();
}
}
在看完abstract关键字的应用之后,您对多态有没有形成一个概念了呢,其实要实现多态还是要有一个面向抽象的编程思维,这一点是很重要的
———— 以上选段摘自耿祥义《Java2实用教程》
了解了面向抽象的编程思维,以及看了这么多的有关多态的小案例,接下来就让我们到实战中感受一下多态所带来的魅力吧
//构造一个抽象几何形状类 —— 实现不同子类几何形状面积的求解
public abstract class Gemotrey {
public abstract double getArea();
}
//柱类 —— 面向抽象类Gemotrey,为具体底面几何图形提供总抽象类接口
public class Pillar {
Gemotrey bottom; //底面几何图形对象
double height; //柱体的高
//传入具体的底面几何图形和柱体的高
public Pillar(Gemotrey bottom, double height) {
this.bottom = bottom;
this.height = height;
}
//对外获取柱体体积
public double getVolume(){
if(bottom == null){
System.out.println("没有底,无法计算面积");
return -1;
}
return bottom.getArea() * height;
//通过具体的几何图形去重写抽象父类的获取面积方法
}
}
//圆类,继承自抽象类Gemotrey
public class Circle extends Gemotrey{
double r;
public Circle(double r) {
this.r = r;
}
@Override
public double getArea() {
return 3.14 * r * r;
}
}
//矩形类,继承自抽象类Gemotrey
public class Rectangle extends Gemotrey{
int a,b;
public Rectangle(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public double getArea() {
return a * b;
}
}
//测试类
public class test {
public static void main(String[] args) {
Gemotrey bottom; //几何形状底面对象
Pillar pillar; //柱类对象
int height = 50;
//1.无底的对象
bottom = null;
pillar = new Pillar(bottom,height);
System.out.println("-----------");
System.out.println("无底的对象面积为:" + pillar.getVolume());
//2.圆形底对象
bottom = new Circle(10);
pillar = new Pillar(bottom,height);
System.out.println("-----------");
System.out.println("圆形底对象面积为:" + pillar.getVolume());
//3.矩形底对象
bottom = new Rectangle(20,15);
pillar = new Pillar(bottom,height);
System.out.println("-----------");
System.out.println("矩形底对象为:" + pillar.getVolume());
}
}
public abstract class SIM {
public abstract void setNumber(String number); //设置电话号码
public abstract String getNumber(); //获取电话号码
public abstract String getCoreName(); //获取电话卡公司
}
public class MobileOfTelecom extends SIM{
String number;
@Override
public void setNumber(String number) {
this.number = number;
}
@Override
public String getNumber() {
return number;
}
@Override
public String getCoreName() {
return "中国电信";
}
}
public class SIMOfChinaMobile extends SIM{
String number;
@Override
public void setNumber(String number) {
this.number = number;
}
@Override
public String getNumber() {
return number;
}
@Override
public String getCoreName() {
return "中国移动";
}
}
public class SIMOfChinaUNnicom extends SIM{
String number;
@Override
public void setNumber(String number) {
this.number = number;
}
@Override
public String getNumber() {
return number;
}
@Override
public String getCoreName() {
return "中国联通";
}
}
public class MobilePhone {
SIM sim;
public void useISM(SIM sim){
this.sim = sim;
}
public void showMess(){
System.out.println("您使用的手机号码是:" + sim.getNumber());
System.out.println("您使用的手机卡公司是:" + sim.getCoreName());
}
}
public static void main(String[] args) {
SIM sim; //SIM电话卡类
MobilePhone mobilePhone = new MobilePhone(); //移动电话类
//1.中国电信
sim = new MobileOfTelecom();
sim.setNumber("18958473306"); //设置电话号码
mobilePhone.useISM(sim); //传入移动电话卡
mobilePhone.showMess(); //显示信息
System.out.println("------------");
//2.中国移动
sim = new SIMOfChinaMobile();
sim.setNumber("13955348743");
mobilePhone.useISM(sim);
mobilePhone.showMess();
System.out.println("------------");
//3.中国联通
sim = new SIMOfChinaUNnicom();
sim.setNumber("13284835562");
mobilePhone.useISM(sim);
mobilePhone.showMess();
}
所谓的开-闭原则(Open-Closed Principle),就是让设计的系统对扩展开发,对修改关闭
我们通过一张框架图来具体理解一下
本文,我们重点讲解了面向对象的第三大特征——多态,讲到了多态存在所必不可少的一块,也就是实现上转型对象,然后说道了继承和多态之间的关系,初步地了解了多态的概念,接着来到了主题部分,也就是关键abstract的讲解,继而引申出了抽象类和抽象方法,了解了这些之后呢,我们又形成了一个面向抽象的编程思维,在实战案例中感受到了如如何运用这种思维去实现一个多态,最后我们讲到了企业开发中所需要遵循的【开-闭】原则,提到了何处需要开,何处又需要关对多态也有了一个完整的思维体系
好了,这就是本文要讲述的所有内容,感谢您对本文的观看,如果错误请于评论区或私信指出