Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多重继承在Java8中的使用_Java_Oop_Inheritance_Multiple Inheritance_Java 8 - Fatal编程技术网

多重继承在Java8中的使用

多重继承在Java8中的使用,java,oop,inheritance,multiple-inheritance,java-8,Java,Oop,Inheritance,Multiple Inheritance,Java 8,我是在使用Java8的功能还是误用了它 请参考下面的代码和解释,了解为什么选择这样 public interface Drawable { public void compileProgram(); public Program getProgram(); default public boolean isTessellated() { return false; } default public boolean isInstance

我是在使用Java8的功能还是误用了它

请参考下面的代码和解释,了解为什么选择这样

public interface Drawable {
    public void compileProgram();

    public Program getProgram();

    default public boolean isTessellated() {
        return false;
    }

    default public boolean isInstanced() {
        return false;
    }

    default public int getInstancesCount() {
        return 0;
    }

    public int getDataSize();

    public FloatBuffer putData(final FloatBuffer dataBuffer);

    public int getDataMode();

    public boolean isShadowReceiver();

    public boolean isShadowCaster();    //TODO use for AABB calculations

    default public void drawDepthPass(final int offset, final Program depthNormalProgram, final Program depthTessellationProgram) {
        Program depthProgram = (isTessellated()) ? depthTessellationProgram : depthNormalProgram;
        if (isInstanced()) {
            depthProgram.use().drawArraysInstanced(getDataMode(), offset, getDataSize(), getInstancesCount());
        }
        else {
            depthProgram.use().drawArrays(getDataMode(), offset, getDataSize());
        }
    }

    default public void draw(final int offset) {
        if (isInstanced()) {
            getProgram().use().drawArraysInstanced(getDataMode(), offset, getDataSize(), getInstancesCount());
        }
        else {
            getProgram().use().drawArrays(getDataMode(), offset, getDataSize());
        }
    }

    default public void delete() {
        getProgram().delete();
    }

    public static int countDataSize(final Collection<Drawable> drawables) {
        return drawables.stream()
                .mapToInt(Drawable::getDataSize)
                .sum();
    }

    public static FloatBuffer putAllData(final List<Drawable> drawables) {
        FloatBuffer dataBuffer = BufferUtils.createFloatBuffer(countDataSize(drawables) * 3);
        drawables.stream().forEachOrdered(drawable -> drawable.putData(dataBuffer));
        return (FloatBuffer)dataBuffer.clear();
    }

    public static void drawAllDepthPass(final List<Drawable> drawables, final Program depthNormalProgram, final Program depthTessellationProgram) {
        int offset = 0;
        for (Drawable drawable : drawables) {
            if (drawable.isShadowReceiver()) {
                drawable.drawDepthPass(offset, depthNormalProgram, depthTessellationProgram);
            }
            offset += drawable.getDataSize();   //TODO count offset only if not shadow receiver?
        }
    }

    public static void drawAll(final List<Drawable> drawables) {
        int offset = 0;
        for (Drawable drawable : drawables) {
            drawable.draw(offset);
            offset += drawable.getDataSize();
        }
    }

    public static void deleteAll(final List<Drawable> drawables) {
        drawables.stream().forEach(Drawable::delete);
    }
}


public类框实现了镶嵌可绘制、InstancedDrawable{
//
静止的{
英国政府工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的纹理,工作人员的工作人员的工作人员的纹理,工作人员的工作人员的工作人员的工作人员的纹理,混合颜色,混合颜色,混合颜色,颜色,混合颜色,颜色,德国军队军队的混合颜色,军队军队的颜色,军队的军队军队军队的军队的颜色,男男男男男色,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,缓冲,数组,缓冲,数组,数组,数组,数组,缓冲,数组,数组,数组,数组,数组U计划| GL_活动|原子|计数器| GL_活动|资源| GL_缓冲|不可变|存储;
int KEEP_OWN_IMPORTS=UNIFORM_PROJECTION_MATRIX.getLocation()| VS_POSITION.getLocation();
}
//
私有缓冲区数据;
私人项目;
专用最终浮子宽度、高度、深度;
公用框(最终浮动宽度、最终浮动高度、最终浮动深度){
这个。宽度=宽度;
高度=高度;
这个。深度=深度;
数据=generateBox();
data.clear();
}
@凌驾
公共无效编译器程序(){
程序=新程序(
新的VertexShader(“数据/着色器/box.vs.glsl”).compile(),
新的FragmentShader(“data/shaders/box.fs.glsl”).compile()
).compile().usingUniforms(
一致_模型_矩阵,
统一视图矩阵,
均匀投影矩阵,
均匀阴影矩阵
);
}
@凌驾
public int getInstanceCount(){
返回100;
}
@凌驾
公共程序getProgram(){
返回程序;
}
@凌驾
public int getDataSize(){
返回6*6;
}
@凌驾
公共浮动缓冲区putData(最终浮动缓冲区数据缓冲区){
FloatBuffer returnData=dataBuffer.put(数据);
data.clear();//清除以重置数据状态
返回数据;
}
@凌驾
public int getDataMode(){
返回GL_三角形;
}
@凌驾
公共布尔值isShadowReceiver(){
返回true;
}
@凌驾
公共布尔值isShadowCaster(){
返回true;
}
私有FloatBuffer generateBox(){
FloatBuffer-boxData=BufferUtils.createFloatBuffer(6*6*3);
//将数据放入boxData
return(FloatBuffer)boxData.clear();
}
}
首先,我将介绍如何编写此代码的步骤:

  • 我从
    Drawable
    接口开始,每个实现都有自己的
    drawDepthPass
    draw
    delete
    方法

  • delete
    重构为
    default
    方法很简单,也很简单,不应该出错

  • 然而,为了能够重构
    drawDepthPass
    draw
    我需要访问
    Drawable
    是否被细分和/或实例化,所以我添加了公共(非默认的)方法
    IsEstessellated()
    IsInstanceCount()

  • 然后我发现在每个
    可绘制的
    中实现它们会有点麻烦,因为我们程序员都很懒

  • 因此,我将
    default
    方法添加到
    Drawable
    ,给出了最基本的
    Drawable
    方法的行为

  • 然后我发现我仍然很懒,不想在这里为细分和实例化的变体手动实现它

  • 因此,我创建了
    TessellatedDrawable
    instancedrawable
    ,分别提供
    default
    istesellated()
    isInstanced()
    。在
    InstancedDrawable
    中,我撤销了
    getInstanceCount()
    default
    实现

  • 因此,我可以有以下几点:

    • 普通
      Drawable
      公共A类实现Drawable
    • 镶嵌
      可绘制
      公共类A实现镶嵌可绘制
    • Instanced
      Drawable
      公共A类实现InstancedDrawable
    • 细分和实例化
      可绘制
      公共类A实现了InstancedDrawable、细分可绘制
    为了确保编译和运行正常,
    实现了InstancedDrawable,TessellatedDrawable
    可以被Java 8完美地处理,因为功能应该来自哪个接口是没有任何歧义的

    现在我来谈谈我自己的OOP设计评估:

    • 每个
      可绘制的
      实际上都是一个
      可绘制的
      ,因此
      集合
      不会中断
    • 可以将所有的
      镶嵌可绘制
      和/或
      InstancedDrawable
      分组,这与它的具体实现方式无关
    我还有其他想法:

    • 使用更传统的分层方法,但我忽略了这一点,因为它最终会导致:

    • 抽象类AbstractDrawable

    • class Drawable扩展了AbstractDrawable
    • class TessellatedDrawable扩展了AbstractDrawable
    • class InstancedDrawable扩展了AbstractDrawable
    • class InstancedTessellatedDrawable扩展了AbstractDrawable
    我也考虑过构建器模式,但是当您创建某个对象的许多独特实例时,将使用该模式,这不是我们在这里所做的,也不是关于对象的构造函数


    因此,第一个也是最后一个问题是:我是在使用Java 8的功能还是误用了它?

    首先,如果它有效,并且它做了您想做的事情,那么没有危险
    public interface TessellatedDrawable extends Drawable {
        @Override
        default public boolean isTessellated() {
            return true;
        }
    }
    
    public interface InstancedDrawable extends Drawable {
        @Override
        default public boolean isInstanced() {
            return true;
        }
    
        @Override
        public int getInstancesCount();
    }
    
    public class Box implements TessellatedDrawable, InstancedDrawable {
        //<editor-fold defaultstate="collapsed" desc="keep-imports">
        static {
            int KEEP_LWJGL_IMPORTS = GL_2_BYTES | GL_ALIASED_LINE_WIDTH_RANGE | GL_ACTIVE_TEXTURE | GL_BLEND_COLOR | GL_ARRAY_BUFFER | GL_ACTIVE_ATTRIBUTE_MAX_LENGTH | GL_COMPRESSED_SLUMINANCE | GL_ALPHA_INTEGER | GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH | GL_ALREADY_SIGNALED | GL_ANY_SAMPLES_PASSED | GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH | GL_ACTIVE_PROGRAM | GL_ACTIVE_ATOMIC_COUNTER_BUFFERS | GL_ACTIVE_RESOURCES | GL_BUFFER_IMMUTABLE_STORAGE;
            int KEEP_OWN_IMPORTS = UNIFORM_PROJECTION_MATRIX.getLocation() | VS_POSITION.getLocation();
        }
    //</editor-fold>
        private FloatBuffer data;
        private Program program;
    
        private final float width, height, depth;
    
        public Box(final float width, final float height, final float depth) {
            this.width = width;
            this.height = height;
            this.depth = depth;
            data = generateBox();
            data.clear();
        }
    
        @Override
        public void compileProgram() {
            program = new Program(
                    new VertexShader("data/shaders/box.vs.glsl").compile(),
                    new FragmentShader("data/shaders/box.fs.glsl").compile()
            ).compile().usingUniforms(
                            UNIFORM_MODEL_MATRIX,
                            UNIFORM_VIEW_MATRIX,
                            UNIFORM_PROJECTION_MATRIX,
                            UNIFORM_SHADOW_MATRIX
                            );
        }
    
        @Override
        public int getInstancesCount() {
            return 100;
        }
    
        @Override
        public Program getProgram() {
            return program;
        }
    
        @Override
        public int getDataSize() {
            return 6 * 6;
        }
    
        @Override
        public FloatBuffer putData(final FloatBuffer dataBuffer) {
            FloatBuffer returnData = dataBuffer.put(data);
            data.clear();   //clear to reset data state
            return returnData;
        }
    
        @Override
        public int getDataMode() {
            return GL_TRIANGLES;
        }
    
        @Override
        public boolean isShadowReceiver() {
            return true;
        }
    
        @Override
        public boolean isShadowCaster() {
            return true;
        }
    
        private FloatBuffer generateBox() {
            FloatBuffer boxData = BufferUtils.createFloatBuffer(6 * 6 * 3);
    
            //put data into boxData
    
            return (FloatBuffer)boxData.clear();
        }
    }