java实现多继承
大家都知道java的基本特性是单继承,这正是java的优势之一。没有像c++那样的多继承使java更加的通俗易懂。但是存在即合理,java阉割了多继承肯定有其他的方式来补救。
先看一个例子
这是父类接口
public interface Father {
public void work();
}
public interface Mother {
public void cook();
}
父类的实现类
public class FatherImpl implements Father{
@Override
public void work() {
System.out.println("FatherImpl->work");
}
}
public class MotherImpl implements Mother{
@Override
public void cook() {
System.out.println("MotherImpl->cook");
}
}
子类实现多继承
package moreextends;
import singleton.Singleton;
/**
* 版本一
* @author gejianmin
* 缺点 :
* 1.不能用直接用父类直接实例化子类对象
* 2.不能用super关键字调用父类
* 本质 :
* 出现缺点的本质是son的是没有父类。
*/
public class Son implements Father,Mother{
private Father father = new FatherImpl();
private Mother mother = new MotherImpl();
@Override
public void cook() {
//mother.cook(); 可以调用‘父类’方法
System.out.println("son->cook");
}
@Override
public void work() {
//father.work();
System.out.println("son->cook");
}
}
/**
* 版本二
* @author gejianmin
* 优点:
* 可以实现两个父类中所有方法的重写
* 缺点:
* 每次创建一个son类的时候都会创建三个实例
*
*/
class Son2 implements Father,Mother{
class Son_extends_father extends FatherImpl{
@Override
public void work() {
//super.work();
System.out.println("son2重写父类方法");
}
}
class Son_extends_mother extends MotherImpl{
@Override
public void cook() {
//super.cook();
System.out.println("son2重写另一个父类方法");
}
}
private MotherImpl son_mother = new Son_extends_mother();
private FatherImpl son_father = new Son_extends_father();
@Override
public void cook() {
son_mother.cook();
}
@Override
public void work() {
son_father.work();
}
}
通过上面的例子应该就能模拟实现java实现多继承了。
设计模式的插入
设计模式的好处很多,简洁易懂,扩展性高,条理清楚,在大项目中不容易使一个类大到爆。了解设计模式后习惯性的运用这些模式来改造类,这样有利于对以后大型网站的架构。
创建对象最好使用单例模式
如果是写后台的代码,尽量不要出现 new 这个关键字,虽然用起来很爽,但是如果几十万,几百万人访问这个网站,每人都new出那个对象,很容易报内存溢出的错。所以为了网站能在上线后多坚持一段时间,那些经常用的对象就要用单例模式了。
单例模式: 这个设计模式有大约7种实现方式。懒汉,饿汉,内部类,双重锁。基本上最常用的就是这几种。
饿汉式:类加载的时候创建对象。
懒汉式:调用的时候创建对象。
内部类:我称他为懒汉中的懒汉,在类加载的时候不创建,只有在真正使用这个对象的时候才会创建。
双重锁:就是拿对象当成锁,调用里面的对象有两道锁。这样保证线程安全。
这是单例模式的七种用法连接 http://cantellow.iteye.com/blog/838473
如果写了上面的代码,可以通过单例模式来改造一下
package moreextends;
/**
* 单利模式版本一
*
* @author gejianmin 懒汉线程安全单利
*/
public class Singleton {
private static Father father;
private static Mother mother;
private static Son3 son3;
public static synchronized Son3 getSon3() {
if (son3 == null) {
son3 = new Son3();
}
return son3;
}
public static synchronized Father getFather() {
if (father == null) {
father = new Son_extends_father();
}
return father;
}
public static synchronized Mother getMother() {
if (mother == null) {
mother = new Son_extends_mother();
}
return mother;
}
// 锁住构造函数
private Singleton() {
}
}
/**
* 单利模式版本二
*
* @author gejianmin 内部类实现单利模式 优点:线程安全,懒汉中的懒汉。
* 原理:因为走静态类,所以线程安全。并且Singleton2类被classload装载后并没有暴露里面的内部类, 只有在调用他的 Get*
* 方法的时候才会实例化对象
*/
class Singleton2 {
private static class GetProxySon3 {
private static final ProxySon3 INSTANCE = new ProxySon3();
}
public static final ProxySon3 getProxySon3() {
return GetProxySon3.INSTANCE;
}
private static class GetFather {
private static final Father INSTANCE = new Son4_extends_father();
}
public static final Father getFather() {
return GetFather.INSTANCE;
}
private static class GetMother {
private static final Mother INSTANCE = new Son4_extends_mother();
}
public static final Mother getMother() {
return GetMother.INSTANCE;
}
private static class GetSon4 {
private static final Son4 INSTANCE = new Son4();
}
public static final Son4 getSon4() {
return GetSon4.INSTANCE;
}
private Singleton2() {
}
}
改造Son类
package moreextends;
/**
* 版本三
* @author gejianmin
* 优化版本二 使用懒汉单利模式收集对象
*/
public class Son3 implements Father,Mother{
//相对于版本二改动的地方
//private MotherImpl son_mother = new Son_extends_mother();
//private FatherImpl son_father = new Son_extends_father();
@Override
public void cook() {
Singleton.getMother().cook();
}
public void work() {
Singleton.getFather().work();
}
}
class Son_extends_father extends FatherImpl{
@Override
public void work() {
//super.work();
System.out.println("son3重写父类方法");
}
}
class Son_extends_mother extends MotherImpl{
@Override
public void cook() {
// TODO Auto-generated method stub
//super.cook();
System.out.println("son3重写另一个父类方法");
}
}
package moreextends;
/**
* 版本三
* @author gejianmin
* 优化版本二 使用懒汉单利模式收集对象
*/
public class Son4 implements Father,Mother{
//相对于版本二改动的地方
//private MotherImpl son_mother = new Son_extends_mother();
//private FatherImpl son_father = new Son_extends_father();
@Override
public void cook() {
Singleton2.getMother().cook();
}
public void work() {
Singleton2.getFather().work();
}
}
class Son4_extends_father extends FatherImpl{
@Override
public void work() {
//super.work();
System.out.println("son4重写父类方法");
}
}
class Son4_extends_mother extends MotherImpl{
@Override
public void cook() {
// TODO Auto-generated method stub
//super.cook();
System.out.println("son4重写另一个父类方法");
}
}
Son子类继承后如果想再扩充,可以用装饰模式和代理模式
备注:装饰模式和代理模式的区别
装饰模式:通过构造函数将被装饰的类传到我的Decorator中这样在客户端调用的时候能看到我的原本的类(Son3)
package decorator;
import moreextends.Father;
import moreextends.Mother;
import moreextends.Son3;
public class Decorator implements Father,Mother{
private Son3 son3;
public Decorator(Son3 son3){
this.son3 = son3;
}
@Override
public void cook() {
System.out.println("装饰");
son3.cook();
}
@Override
public void work() {
System.out.println("装饰");
son3.work();
}
}
//客户端调用
public class client{
public static void main(String[] args){
Decorator decorator = new Decorator(Singleton.getSon3()); //这里也可以将Decorator类用单例模式创建
decorator.work();
decorator.cook();
}
}
静态代理模式:通过继承目标类或者实现接口的方式拿到实例对象。再在proxy中进行包装。客户端调用的时候不知道目标类是什么(但从客户端来看是不知道目标类是Son3的)。
public class ProxySon3 extends Son3{
@Override
public void cook() {
System.out.println("静态代理->cook");
super.cook();
}
@Override
public void work() {
System.out.println("静态代理->work");
super.work();
}
}
pubilc class Client{
public static void main(String[] args){
ProxySon3 proxy = new ProxySon3();
proxy.work();
proxy.cook();
}
}