Use concrete types instead of abstract types

- ResourceId -> DiscreteResourceId/ContinuousResourceId
- Resource -> DiscreteResource/ContinuousResource

In addition, stop sharing the implementations in the super classes

Change-Id: I44662f6b7c23a23c30844a5b693e1cabab2cc091
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java b/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java
index 9efbbd1..9e9468a 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java
@@ -16,8 +16,13 @@
 package org.onosproject.net.newresource;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
 
+import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkArgument;
 
 /**
  * Represents a resource path which specifies a resource which can be measured
@@ -28,14 +33,20 @@
  * </p>
  */
 @Beta
-// TODO: consider how to restrict the visibility
-public final class DiscreteResource extends Resource {
-    protected DiscreteResource() {
-        super();
+public final class DiscreteResource implements Resource {
+    private final DiscreteResourceId id;
+
+    DiscreteResource(DiscreteResourceId id) {
+        this.id = id;
     }
 
-    DiscreteResource(ResourceId id) {
-        super(id);
+    protected DiscreteResource() {
+        this.id = ResourceId.ROOT;
+    }
+
+    @Override
+    public DiscreteResourceId id() {
+        return id;
     }
 
     /**
@@ -53,6 +64,36 @@
     }
 
     @Override
+    public List<Object> components() {
+        return id.components;
+    }
+
+    @Override
+    public Object last() {
+        if (id.components.isEmpty()) {
+            return null;
+        }
+        return id.components.get(id.components.size() - 1);
+    }
+
+    @Override
+    public DiscreteResource child(Object child) {
+        checkArgument(!(child instanceof Class<?>));
+
+        return new DiscreteResource(id().child(child));
+    }
+
+    @Override
+    public ContinuousResource child(Class<?> child, double value) {
+        return new ContinuousResource(id.child(child), value);
+    }
+
+    @Override
+    public Optional<DiscreteResource> parent() {
+        return Optional.ofNullable(id.parent()).map(DiscreteResource::new);
+    }
+
+    @Override
     public int hashCode() {
         // the value returing from volume() is excluded due to optimization
         return id().hashCode();
@@ -70,4 +111,12 @@
         // the value returing from volume() is excluded due to optimization
         return Objects.equals(this.id(), other.id());
     }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("id", id)
+                .add("volume", volume())
+                .toString();
+    }
 }