抽象类的具体应用可以看下这个简单的例子:
- 不要去继承一个已经实现好的类-----因为有抽象类和接口
- 下面是一个抽象类的用法
Code
package com.miao.four.demo3;
abstract class Person
{
private String name ;
private int age ;
public Person(String name,int age)
{
this.setName(name) ;
this.setAge(age) ;
}
public void setName(String name)
{
this.name = name ;
}
public void setAge(int age)
{
this.age = age ;
}
public String getName()
{
return this.name ;
}
public int getAge()
{
return this.age ;
}
// 将说话的内容作为一个抽象方法,通过子类去实现
public void say()
{
System.out.println(this.getContent()) ;
}
public abstract String getContent() ;
};
// 假设人分为两种 :一种是工人,一种是学生
// 工人有工资,学生有成绩
// 不管是学生还是工人,肯定都可以说话
// 说话的内容不一样
class Worker extends Person
{
private float salary ;
public Worker(String name,int age,float salary)
{
super(name,age) ;
this.setSalary(salary) ;
}
public void setSalary(float salary)
{
this.salary = salary ;
}
public float getSalary()
{
return this.salary ;
}
public String getContent()
{
return "工人说 --> 姓名:"+super.getName()+",年龄:"+super.getAge()+",工资:"+this.getSalary() ;
}
};
class Student extends Person
{
private float score ;
public Student(String name,int age,float score)
{
super(name,age) ;
this.setScore(score) ;
}
public void setScore(float score)
{
this.score = score ;
}
public float getScore()
{
return this.score ;
}
public String getContent()
{
return "学生说 --> 姓名:"+super.getName()+",年龄:"+super.getAge()+",成绩:"+this.getScore() ;
}
};
public class OODemo03
{
public static void main(String args[])
{
Person p = null ;
// p = new Student("张三",30,90) ;
p = new Worker("张三",30,3000) ;
p.say() ;
}
};
package com.miao.four.demo3;
abstract class Person
{
private String name ;
private int age ;
public Person(String name,int age)
{
this.setName(name) ;
this.setAge(age) ;
}
public void setName(String name)
{
this.name = name ;
}
public void setAge(int age)
{
this.age = age ;
}
public String getName()
{
return this.name ;
}
public int getAge()
{
return this.age ;
}
// 将说话的内容作为一个抽象方法,通过子类去实现
public void say()
{
System.out.println(this.getContent()) ;
}
public abstract String getContent() ;
};
// 假设人分为两种 :一种是工人,一种是学生
// 工人有工资,学生有成绩
// 不管是学生还是工人,肯定都可以说话
// 说话的内容不一样
class Worker extends Person
{
private float salary ;
public Worker(String name,int age,float salary)
{
super(name,age) ;
this.setSalary(salary) ;
}
public void setSalary(float salary)
{
this.salary = salary ;
}
public float getSalary()
{
return this.salary ;
}
public String getContent()
{
return "工人说 --> 姓名:"+super.getName()+",年龄:"+super.getAge()+",工资:"+this.getSalary() ;
}
};
class Student extends Person
{
private float score ;
public Student(String name,int age,float score)
{
super(name,age) ;
this.setScore(score) ;
}
public void setScore(float score)
{
this.score = score ;
}
public float getScore()
{
return this.score ;
}
public String getContent()
{
return "学生说 --> 姓名:"+super.getName()+",年龄:"+super.getAge()+",成绩:"+this.getScore() ;
}
};
public class OODemo03
{
public static void main(String args[])
{
Person p = null ;
// p = new Student("张三",30,90) ;
p = new Worker("张三",30,3000) ;
p.say() ;
}
};
- 当需要继承多个类时,我们可以用接口,接口也是方法全是抽象方法的抽象类,实现接口的类,也是改接口的子类,也可以进行转型操作
Code
interface A
{
public void fun() ;
}
class B implements A
{
public void fun()
{
System.out.println("Hello World!!!") ;
}
};
public class OODemo04
{
public static void main(String args[])
{
A a = new B() ;//可以看到向上转型操作,由子类为接口对象实例化
a.fun() ;
}
};
interface A
{
public void fun() ;
}
class B implements A
{
public void fun()
{
System.out.println("Hello World!!!") ;
}
};
public class OODemo04
{
public static void main(String args[])
{
A a = new B() ;//可以看到向上转型操作,由子类为接口对象实例化
a.fun() ;
}
};
Code
- 可以看到都是多态性的应用都是子类向父类转型
- 抽象类与接口在使用上如此相似,我们开发时优先使用接口,接口允许多继承
- 接口和抽象类的比较:
- 相同点:对象都不能实例化,通过多态性,都可由子类来实例化
- 不同点:抽象类:
包括一般方法、抽象方法、常量、变量
可以有构造方法,毕竟是一个类
抽象类可以实现多个接口
继承时单继承会有局限
接口:
包括常量,抽象方法。只是在接口定义中省略abstract
不能有构造方法
接口不能继承一个抽象类
解决单继承带来的局限性
- 从设计模式上来说:
接口中都是抽象方法,实现接口的子类必须都得覆写其中的方法,如果子类不希望都覆写,而只是希望使用其中的一个时,那怎么办呢?
- 可以在之中加一个抽象类来实现 接口---->抽象类----->子类 也即是适配器模式Adapter,看下面的例子:
Code
interface A
{
public void fun1() ;
public void fun2() ;
public void fun3() ;
}
abstract class B implements A
{
public void fun1()
{}
public void fun2()
{}
public void fun3()
{}
};
class C extends B
{
public void fun1()
{
System.out.println("HELLO MLDN ") ;
}
};
public class OODemo06
{
public static void main(String args[])
{
A a = new C() ;//虽然C没有直接覆写A,但是c也是A的子类,因为C继承了B,B实现了A
a.fun2() ;//多态的体现
}
};
interface A
{
public void fun1() ;
public void fun2() ;
public void fun3() ;
}
abstract class B implements A
{
public void fun1()
{}
public void fun2()
{}
public void fun3()
{}
};
class C extends B
{
public void fun1()
{
System.out.println("HELLO MLDN ") ;
}
};
public class OODemo06
{
public static void main(String args[])
{
A a = new C() ;//虽然C没有直接覆写A,但是c也是A的子类,因为C继承了B,B实现了A
a.fun2() ;//多态的体现
}
};
- 接口可以进一步扩展---->工厂模式,在上面的USB例子中发现子类与接口紧密耦合,即USB a =new Mp3();发现如果子类需要变化,则我们必须修改客户端,而这在实际的开发中是不好的。可以加上一个工厂来解耦合
Code
package com.miao.four.demo7;
interface USB
{
// 开始工作
public void start() ;
// 停止工作
public void stop() ;
}
class Mp3 implements USB
{
public void start()
{
System.out.println("Mp3开始工作了。。。") ;
}
public void stop()
{
System.out.println("Mp3停止工作了。。。") ;
}
};
class UDisk implements USB
{
public void start()
{
System.out.println("U盘开始工作了。。。") ;
}
public void stop()
{
System.out.println("U盘停止工作了。。。") ;
}
};
// 假设现在要修改子类,则要修改mian方法,是一个程序的客户端
class Factory
{
public static USB getUSBInstance()
{
return new UDisk() ;
}
};
public class OODemo07
{
public static void main(String args[])
{
USB u = Factory.getUSBInstance() ;//这样后以后子类要是有变动,只需改工厂即可
u.start() ;
u.stop() ;
}
};
package com.miao.four.demo7;
interface USB
{
// 开始工作
public void start() ;
// 停止工作
public void stop() ;
}
class Mp3 implements USB
{
public void start()
{
System.out.println("Mp3开始工作了。。。") ;
}
public void stop()
{
System.out.println("Mp3停止工作了。。。") ;
}
};
class UDisk implements USB
{
public void start()
{
System.out.println("U盘开始工作了。。。") ;
}
public void stop()
{
System.out.println("U盘停止工作了。。。") ;
}
};
// 假设现在要修改子类,则要修改mian方法,是一个程序的客户端
class Factory
{
public static USB getUSBInstance()
{
return new UDisk() ;
}
};
public class OODemo07
{
public static void main(String args[])
{
USB u = Factory.getUSBInstance() ;//这样后以后子类要是有变动,只需改工厂即可
u.start() ;
u.stop() ;
}
};
- 重点:抽象类和接口都可以实例化,通过对象的多态性来实例化。