[零基础学JAVA]Java SE面向对象部分-17.面向对象高级(05)

简介:
上季内容回顾:
1、对象的多态性 
2、抽象类和接口
本季主要知识点:
抽象类和接口的实际应用
1、子类对象可以为父类对象实例化,之后调用的方法都是子类中已经被覆写过的方法。 
2、就可以利用此特性,观察抽象类的使用,因为在抽象类中有很多的抽象方法。
抽象类
abstract  class A    
{    
         public  abstract  void fun();    
};    
class B  extends A    
{    
         public  void fun()    
        {    
                System.out.println( "B ==> Hello World");    
        }    
};    
class C  extends A    
{    
         public  void fun()    
        {    
                System.out.println( "C ==> Hello World");    
        }    
};    
public  class Demo01    
{    
         public  static  void main(String args[])    
        {    
                A a =  new B();    
                a.fun();    
        }    
};
image
abstract  class A    
{    
         public  abstract  void fun();    
};    
class B  extends A    
{    
         public  void fun()    
        {    
                System.out.println( "B ==> Hello World");    
        }    
};    
class C  extends A    
{    
         public  void fun()    
        {    
                System.out.println( "C ==> Hello World");    
        }    
};    
public  class Demo01    
{    
         public  static  void main(String args[])    
        {    
                A a =  new C();    
                a.fun();    
        }    
};
image
抽象类是可以实例化的,通过对象的多态性来实例化
抽象类的主要作用是什么呢?抽象类就是类似于一个模板操作 ==>JAVA WEB Servlet程序,提供的就是一个模板。
image
把上面的实际的例子变为程序
abstract  class Err    
{    
         public  void printInfo()    
        {    
                System.out.println( "姓名:"+ this.getName());    
                System.out.println( "班级:"+ this.getCls());    
                System.out.println( "事由:"+ this.getCau());    
        }    
         //得到姓名,由具体的子类去做    
         public  abstract String getName();    
         //得到班级,由具体的子类去做    
         public  abstract String getCls();    
         //得到事由    
         public  abstract String getCau();    
}    
class ZhangSan  extends Err    
{    
         public String getName()    
        {    
                 return  "张三";    
        }    
         public String getCls()    
        {    
                 return  "小五班";    
        }    
         public String getCau()    
        {    
                 return  "因为上课吃东西,所以被老师抓住了,所以要填写违纪卡。 ";    
        }    
}    
class LiSi  extends Err    
{    
         public String getName()    
        {    
                 return  "李四";    
        }    
         public String getCls()    
        {    
                 return  "大五班";    
        }    
         public String getCau()    
        {    
                 return  "因为上课睡觉,所以被老师抓住了,所以要填写违纪卡。 ";    
        }    
}    
public  class Demo02    
{    
         public  static  void main(String args[])    
        {    
                Err e =  new ZhangSan();    
                e.printInfo();    
        }    
}
image
我们改成李四看看效果哈~
abstract  class Err    
{    
         public  void printInfo()    
        {    
                System.out.println( "姓名:"+ this.getName());    
                System.out.println( "班级:"+ this.getCls());    
                System.out.println( "事由:"+ this.getCau());    
        }    
         //得到姓名,由具体的子类去做    
         public  abstract String getName();    
         //得到班级,由具体的子类去做    
         public  abstract String getCls();    
         //得到事由    
         public  abstract String getCau();    
}    
class ZhangSan  extends Err    
{    
         public String getName()    
        {    
                 return  "张三";    
        }    
         public String getCls()    
        {    
                 return  "小五班";    
        }    
         public String getCau()    
        {    
                 return  "因为上课吃东西,所以被老师抓住了,所以要填写违纪卡。 ";    
        }    
}    
class LiSi  extends Err    
{    
         public String getName()    
        {    
                 return  "李四";    
        }    
         public String getCls()    
        {    
                 return  "大五班";    
        }    
         public String getCau()    
        {    
                 return  "因为上课睡觉,所以被老师抓住了,所以要填写违纪卡。 ";    
        }    
}    
public  class Demo02    
{    
         public  static  void main(String args[])    
        {    
                Err e =  new LiSi();    
                e.printInfo();    
        }    
}
调用模板成功了哈~
image 
(模板设计)场景: 
       假设Person分为Worker和Student,工人的属性包括:姓名、年龄、工资,学生的属性包括:姓名、年龄、成绩,那么现在人都可以说话,但是工人和学生说的话肯定不一样。此时,肯定人中的说话方法是固定的,肯定是一个普通方法,只是说话的内容不一样。
abstract  class Person    
{    
         private String name;    
         private  int age;    
         public Person(String name, int age)    
        {    
                 this.name = name;    
                 this.age = age;    
        }    
         public String getName()    
        {    
                 return  this.name;    
        }    
         public  int getAge()    
        {    
                 return  this.age;    
        }    
         public  void talk()    
        {    
                 //这是要说,内容都在此方法中    
                System.out.println( this.getContent());    
        }    
         public  abstract String getContent();    
}    
class Student  extends Person    
{    
         private  float score;    
         public Student(String name, int age, float score)    
        {    
                 super(name,age);    
                 this.score = score;    
        }    
         public String getContent()    
        {    
                 return  "学生说 --> 姓名="+ super.getName()    
                                + ",年龄="+ super.getAge()    
                                + ",成绩="+ this.score;    
        }    
}    
class Worker  extends Person    
{    
         private  float salary;    
         public Worker(String name, int age, float salary)    
        {    
                 super(name,age);    
                 this.salary = salary;    
        }    
         public String getContent()    
        {    
                 return  "工人说 --> 姓名="+ super.getName()    
                                + ",年龄="+ super.getAge()    
                                + ",工资="+ this.salary;    
        }    
}    
public  class Demo03    
{    
         public  static  void main(String args[])    
        {    
                Person p1 =  new Student( "张三",20,90.0f);    
                Person p2 =  new Worker( "李四",30,900.0f);    
                p1.talk();    
                p2.talk();    
        }    
}
image
接口的实际应用
image
分布式代码中最重要的就是要规定好操作的接口。接口就是定义了一个标准,只要按照此标准代码都可以正常使用。
interface A    
{    
         public String getInfo();    
}    
class B  implements A    
{    
         public String getInfo()    
        {    
                 return  "B --> Hello World";    
        }    
}    
class C  implements A    
{    
         public String getInfo()    
        {    
                 return  "C --> Hello World";    
        }    
}    
public  class Demo04    
{    
         public  static  void main(String args[])    
        {    
                A a =  new B();    
                System.out.println(a.getInfo());    
        }    
}
证明接口对象可以实例化,通过对象多态性进行向上转型,接口是可以实例化的。
image
我们改成C看看效果
interface A    
{    
         public String getInfo();    
}    
class B  implements A    
{    
         public String getInfo()    
        {    
                 return  "B --> Hello World";    
        }    
}    
class C  implements A    
{    
         public String getInfo()    
        {    
                 return  "C --> Hello World";    
        }    
}    
public  class Demo04    
{    
         public  static  void main(String args[])    
        {    
                A a =  new C();    
                System.out.println(a.getInfo());    
        }    
}
我们发现都可以利用对象多态性完成操作
image
接口是一个标准。 
  USB接口  --> 只要是实现了USB接口的设备就都可以向USB接口上插。 
举例: 
  假设现在设计一个USB接口,里面只有开始工作和停止工作的操作。主板上有USB接口,表示可以插入任意的USB设备。
interface USB    
{    
         //表示开始工作    
         public  void start();    
         //表示停止工作    
         public  void stop();    
}    
class MainBoard    
{    
         //只要是USB设备就可以插    
         public  static  void plugIn(USB usb)    
        {    
                usb.start();    
                usb.stop();    
        }    
}    
class MP3  implements USB    
{    
         public  void start()    
        {    
                System.out.println( "MP3开始工作");    
        }    
         public  void stop()    
        {    
                System.out.println( "MP3停止工作");    
        }    
}    
class Print  implements USB    
{    
         public  void start()    
        {    
                System.out.println( "打印机开始工作");    
        }    
         public  void stop()    
        {    
                System.out.println( "打印机停止工作");    
        }    
}    
public  class Demo05    
{    
         public  static  void main(String args[])    
        {    
                USB u =  new MP3();    
                MainBoard.plugIn(u);    
        }    
}
现在看下效果
image
如果是打印机呢?
interface USB    
{    
         //表示开始工作    
         public  void start();    
         //表示停止工作    
         public  void stop();    
}    
class MainBoard    
{    
         //只要是USB设备就可以插    
         public  static  void plugIn(USB usb)    
        {    
                usb.start();    
                usb.stop();    
        }    
}    
class MP3  implements USB    
{    
         public  void start()    
        {    
                System.out.println( "MP3开始工作");    
        }    
         public  void stop()    
        {    
                System.out.println( "MP3停止工作");    
        }    
}    
class Print  implements USB    
{    
         public  void start()    
        {    
                System.out.println( "打印机开始工作");    
        }    
         public  void stop()    
        {    
                System.out.println( "打印机停止工作");    
        }    
}    
public  class Demo05    
{    
         public  static  void main(String args[])    
        {    
                USB u =  new Print();    
                MainBoard.plugIn(u);    
        }    
}
image
这就是一个典型的操作,一切以接口标准进行操作。接口规定什么,其就可以完成什么样的工作哈~
举例: 
  听我讲课,听我讲课,我说的是中文,你听的是中文,所以你能听懂,如果你再说话,你肯定也说中文,我听的也是中文。
接口在实际中可以作为一种标准,那么这种标准在使用的时候就可以让类之间进行解耦合操作。 
   接口的重要目的是解耦合:   A --> B
class A    
{    
         public  void fun(B b)    
        {    
                b.print();    
        }    
}    
class B    
{    
         public  void print()    
        {    
                System.out.println( "Hello World!!!");    
        }    
}    
public  class Demo06    
{    
         public  static  void main(String args[])    
        {    
                 new A().fun( new B());    
        }    
}
image
此代码存在的问题: 
  如果现在B类的功能不能直接满足A类的要求了, 需要对B进行扩充或是把B类彻底替换成另外一个C类,那么此时要完成以下步骤:修改A类、增加C类,那么问有没有这样一种可能:修改功能的时候我可以不动类A呢?可以使用接口。
class A    
{    
         public  void fun(X x)    
        {    
                x.print();    
        }    
}    
interface X    
{    
         public  void print();    
}    
class B  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello World!!!");    
        }    
}    
class C  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello Java!!!");    
        }    
}    
public  class Demo06    
{    
         public  static  void main(String args[])    
        {    
                X x =  new C();    
                 new A().fun(x);    
        }    
}
image
问题: 
  在实际的代码中main方法实际上应该是作为一个客户端出现的。 
此时客户端与接口和其接口的子类是直接有关的。代码中肯定不能这样编写,因为会造成客户端(main)与具体的子类耦合。
  JVM的工作原理:
*.class -->JVM -->OS :程序可移植性高。
class A    
{    
         public  void fun(X x)    
        {    
                x.print();    
        }    
}    
interface X    
{    
         public  void print();    
}    
class B  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello World!!!");    
        }    
}    
class C  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello Java!!!");    
        }    
}    
//中间再加入一个过渡端    
class Factory    
{    
         public  static X getInstance(String str)    
        {    
                X x =  null;    
                 if ( "B".equals(str))    
                {    
                         //认为操作的是B类    
                        x =  new B();    
                }    
                 if ( "C".equals(str))    
                {    
                        x =  new C();    
                }    
                 return x;    
        }    
}    
public  class Demo06    
{    
         public  static  void main(String args[])    
        {    
                X x = Factory.getInstance( "B");    
                 new A().fun(x);    
        }    
}
现在在客户端就看不到接口了
image
现在换成C标记
class A    
{    
         public  void fun(X x)    
        {    
                x.print();    
        }    
}    
interface X    
{    
         public  void print();    
}    
class B  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello World!!!");    
        }    
}    
class C  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello Java!!!");    
        }    
}    
//中间再加入一个过渡端    
class Factory    
{    
         public  static X getInstance(String str)    
        {    
                X x =  null;    
                 if ( "B".equals(str))    
                {    
                         //认为操作的是B类    
                        x =  new B();    
                }    
                 if ( "C".equals(str))    
                {    
                        x =  new C();    
                }    
                 return x;    
        }    
}    
public  class Demo06    
{    
         public  static  void main(String args[])    
        {    
                X x = Factory.getInstance( "C");    
                 new A().fun(x);    
        }    
}
image
此时客户端并没有一个具体的子类出现。
class A    
{    
         public  void fun(X x)    
        {    
                x.print();    
        }    
}    
interface X    
{    
         public  void print();    
}    
class B  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello World!!!");    
        }    
}    
class C  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello Java!!!");    
        }    
}    
//中间再加入一个过渡端    
class Factory    
{    
         public  static X getInstance(String str)    
        {    
                X x =  null;    
                 if ( "B".equals(str))    
                {    
                         //认为操作的是B类    
                        x =  new B();    
                }    
                 if ( "C".equals(str))    
                {    
                        x =  new C();    
                }    
                 return x;    
        }    
}    
public  class Demo06    
{    
         public  static  void main(String args[])    
        {    
                 if (args.length!=1)    
                {    
                        System.out.println( "程序参数错误,程序无法运行!");    
                        System.exit(1);    
                }    
                X x = Factory.getInstance(args[0]);    
                 new A().fun(x);    
        }    
}
image 
  以后如果假设要增加新的子类的时候,只需要修改工厂类即可,其他地方不用做太大的修改,即: 
某一个代码的修改不影响被调用处的代码就是好的设计。
上面的例子中执行java Demo06 D出现NullPointerException错误,我们可以这样修改,加个判断 if(x!=null)
class A    
{    
         public  void fun(X x)    
        {    
                 if(x!= null)    
                x.print();    
        }    
}    
interface X    
{    
         public  void print();    
}    
class B  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello World!!!");    
        }    
}    
class C  implements X    
{    
         public  void print()    
        {    
                System.out.println( "Hello Java!!!");    
        }    
}    
//中间再加入一个过渡端    
class Factory    
{    
         public  static X getInstance(String str)    
        {    
                X x =  null;    
                 if ( "B".equals(str))    
                {    
                         //认为操作的是B类    
                        x =  new B();    
                }    
                 if ( "C".equals(str))    
                {    
                        x =  new C();    
                }    
                 return x;    
        }    
}    
public  class Demo06    
{    
         public  static  void main(String args[])    
        {    
                 if (args.length!=1)    
                {    
                        System.out.println( "程序参数错误,程序无法运行!");    
                        System.exit(1);    
                }    
                X x = Factory.getInstance(args[0]);    
                 new A().fun(x);    
        }    
}
image 
  最早:接口直接去通过new 子类取得对象,那么这样造成一个接口与具体的子类直接耦合 
  现在:接口通过一个工厂类取得子类对象(根据传入的参数不同),此时接口与具体子类之间没有直接的耦合关系,所以使用接口可以解耦合。
此设计称为工厂设计模式: 
  接口   -->  工厂 -->  各个的子类对象
总结 
1、重点阐述了抽象类和接口的使用 
2、注意:自己简单总结一下抽象类和接口的不同 
3、工厂设计
############################################################







本文转自redking51CTO博客,原文链接:http://blog.51cto.com/redking/129219 ,如需转载请自行联系原作者
相关文章
|
2月前
|
存储 Java 测试技术
Java基础 - 面向对象
面向对象编程是Java的核心,包含封装、继承、多态三大特性。封装隐藏实现细节,提升代码可维护性与安全性;继承实现类间IS-A关系,支持代码复用;多态通过继承、重写与向上转型,实现运行时方法动态绑定,提升系统扩展性与灵活性。
|
4月前
|
人工智能 Java 编译器
Java:面向对象
本文介绍了Java编程中的核心概念,包括包的命名规范与自动导入机制、构造方法的特点与使用、`this`和`super`关键字的作用、继承的基本规则、访问权限的设置、封装的意义、多态的实现原理以及`static`关键字的用法。通过详细解析每个知识点,并结合代码示例,帮助读者深入理解Java面向对象编程的核心思想与实践技巧。内容适合初学者及进阶开发者学习参考。
109 0
|
6月前
|
缓存 安全 Java
java面试-基础语法与面向对象
本文介绍了 Java 编程中的几个核心概念。首先,详细区分了方法重载与重写的定义、发生阶段及规则;其次,分析了 `==` 与 `equals` 的区别,强调了基本类型和引用类型的比较方式;接着,对比了 `String`、`StringBuilder` 和 `StringBuffer` 的特性,包括线程安全性和性能差异;最后,讲解了 Java 异常机制,包括自定义异常的实现以及常见非检查异常的类型。这些内容对理解 Java 面向对象编程和实际开发问题解决具有重要意义。
|
9月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
102 1
|
10月前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
87 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
|
12月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
10月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
176 2
|
12月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
97 4
|
12月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
11月前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
79 0