从面向对象设计的角度来说,抽象类与抽象方法,接口都是必不可少的内容,正是这些概念以及实际运用,够成了java面向对象的核心与强大,抽象类,方法是和多态密不可分的设计范式....
何为多态?简单的说就是一类事物的多种形态,基本类型有多种形态(类型自动转换),方法有多种形态(重载:同名不同参),引用类型的多态则相对复杂,比如说,一个描述人类的类,里面有个方法叫说话,不同语言的人说出来是不一样的,中国人说汉语,外国人说我听不懂的鸟语...在人类这个类中怎么实现说话呢?可想而知是不现实的,最好的方法就是把这个说话的方法设计成抽象方法,不提供具体实现,让继承人类的子类去重写(重写:同名,同参,同返回,范围不能变小,异常不能变大)这个方法...
何为抽象类?抽象类是从其他若干个具有相同属性与行为的类中进一步抽象出来的类,可以设计方法,属性,如果把类设计为抽象类,那么这个类是不能被实例化的,只能被继承的子类(子类也可以为抽象类,也可以不是)间接使用,抽象类有构造,是一个完整的类,抽象类中可以包含抽象方法,也可以不含,那么问题来了,既然把类设计成抽象,肯定是用于设计多态用的,一般都会包含抽象方法:
子类继承了抽象类,如果抽象类中含有抽象方法,那么子类也继承了抽象方法,包含抽象方法的类必须是抽象类,不然子类就必须重写抽象方法,就是提供具体实现,完成多态,
下面3条原则保证了抽象方法必须重写:
1、必须用public abstract修饰抽象方法,private ,static 都不能用于修饰
2、包含抽象方法的类必须是抽象类
3、抽象类可以不含抽象方法
代码示例:
- <span style="font-size:18px;">package OOTest;
- public abstract class Human {//抽象父类
- private final int time=++count;//对象计数器
- private static int count;//静态池
- //属性封装
- private String name;//封装三步:隐藏属性,提供getter与setter方法,构造中调用setter初始化
- private int age;
- private String sex;
- //getter&&setter
- public String getName(){
- return this.name;
- }
- public void setName(String name){
- //处理代码:姓名不能为空,且不能包含数字
- if(name.length()==0){
- System.out.println("姓名不能为空");
- }
- else if(this.isWrongName(name)){//调用私有方法处理
- System.out.println("非法姓名,不能包含数字");
- }
- else{
- this.name=name;
- }
- }
- private boolean isWrongName(String name){//判断非法姓名输入(私有)
- char[] ch=name.toCharArray();
- for(int i=0;i<ch.length;i++){
- try{
- int s=Integer.parseInt(String.valueOf(ch[i]));
- s++;//废
- return true;
- }
- catch(Exception e){
- continue;//出错就继续下一次循环转换
- }
- }
- return false;//先返回错误
- }
- public int getAge(){
- return this.age;
- }
- public void setAge(int age){
- if(age<=0){
- System.out.println("年龄有误");
- }
- else{
- this.age=age;
- }
- }
- public String getSex(){
- return this.sex;
- }
- public void setSex(String sex){
- if(sex.length()>1||sex.length()==0){
- System.out.println("性别设定错误");
- }
- else if(sex.toCharArray()[0]=='男'||sex.toCharArray()[0]=='女'){
- this.sex=sex;
- }
- else{
- System.out.println("性别设定错误");
- }
- }
- //构造
- public Human(){//无参
- this("无1名氏",25,"男");
- }
- public Human(String name,int age,String sex){//全参
- this.setName(name);
- this.setAge(age);
- this.setSex(sex);
- }
- //抽象方法
- public abstract void speak();//说话
- public abstract void work();//工作
- public abstract void eat();
- //获取对象创建数目
- public int getHumanClassUseTimes(){
- return this.time;
- }
- }
- </span>
子类:
- <span style="font-size:18px;">package OOTest;
- public class Chinese extends Human {
- public Chinese() {
- // TODO Auto-generated constructor stub
- }
- public Chinese(String name, int age, String sex) {
- super(name, age, sex);
- // TODO Auto-generated constructor stub
- }
- public void eat() {
- System.out.println(this.getName()+"中国人用筷子吃饭");
- }
- public void speak() {
- System.out.println("中国人说汉语"+this.getSex());
- }
- public void work() {
- System.out.println("中国人干活踏实勤快"+this.getAge());
- }
- }
- </span>
测试类:
- <span style="font-size:18px;">package OOTest;
- public class Test {
- public static void main(String[] args) {
- Human h=new Chinese();
- h.eat();
- h.speak();
- h.work();
- System.out.println("Human类被实例化:"+h.getHumanClassUseTimes()+"次");
- Human h1=new Chinese();
- System.out.println("Human类被实例化:"+h1.getHumanClassUseTimes()+"次");
- }
- }</span>
运行结果:
非法姓名,不能包含数字
null中国人用筷子吃饭
中国人说汉语男
中国人干活踏实勤快25
Human类被实例化:1次
非法姓名,不能包含数字
Human类被实例化:2次
- 上一篇:java中方法参数传递问题