I have an abstract class in apex with several properties that I would like to override in a child class. According to the documentation, properties support both the override and virtual access modifiers. However, when I try to use either of them in either the parent or child class, I get an error saying that variables cannot be marked as virtual/override. Here is a facsimile of the code that causes this error:
public abstract class Row{
public virtual double value{
get{return value==null ? 0 : value;}
set;
}
}
public class SummaryRow extends Row{
private list<Row> childRows;
public override double value{
get{
totalValue = 0;
for(Row childRow:childRows){
totalvalue += childRow.value;
}
return totalValue;
}
}
}
Is this functionality not supported, or is there something that I am missing?
Thanks in advance.
Unfortunately, as far as I know that is a mistake in the documentation. I've only been able to apply the override and virtual modifiers to methods. You can, of course, get the desired effect by manually writing your property getter/setter methods:
public abstract class TestRow {
public Double value;
public virtual Double getValue() {
return value==null ? 0 : value;
}
public void setValue(Double value) {
this.value = value;
}
}
public class SummaryTestRow extends TestRow {
private list<TestRow> childRows;
public override Double getValue() {
Double totalValue = 0;
for(TestRow childRow : childRows){
totalValue += childRow.value;
}
return totalValue;
}
}
Related
I'm trying to create a class heirachy for a game, there is an Item class which is the base class for all items in the game. The problem is that some derived items (like potion) might not implement some of the abstract methods defined by the item.
Is it ok for derived classes to implement an abstract method with "do nothing"?
Example: https://dotnetfiddle.net/jJABN1
using System;
using System.Collections.Generic;
public abstract class Item
{
public abstract void Use();
}
public class Potion : Item
{
public override void Use()
{
// do nothing
return;
}
}
public class Sword : Item
{
public override void Use()
{
Console.WriteLine("Sword used!");
return;
}
}
public class Program
{
public static void Main()
{
List<Item> items = new List<Item>();
Item potion = new Potion();
Item sword = new Sword();
items.Add(potion);
items.Add(sword);
for (int i = 0; i < items.Count; i++)
{
Item item = items[i];
item.Use();
}
}
}
One of Robert Martin's SOLID Principles - Interface Segregation Principle addresses this situation. It basically says that a client should not be exposed to methods it doesn't need.
An example of violating the Interface Segregation Principle:
// Abstraction
public abstract class Printer
{
public abstract void Print();
public abstract void Scan();
}
// Implementations
public class SomeAllInOnePrinter : Printer
{
public override void Print()
{
Console.WriteLine("Printing...");
}
public override void Scan()
{
Console.WriteLine("Scanning...");
}
}
public class SomeBasicPrinter : Printer
{
public override void Print()
{
Console.WriteLine("Printing...");
}
public override void Scan()
{
// Basic printers can't scan
}
}
This is usually solved by separating an abstract class to multiple smaller abstract classes that can optionally inherit one other:
// Abstractions
public abstract class Printer
{
public abstract void Print();
}
public abstract class AllInOnePrinter : Printer
{
public abstract void Scan();
}
// Implementations
public class SomeAllInOnePrinter : AllInOnePrinter
{
public override void Print()
{
Console.WriteLine("Printing...");
}
public override void Scan()
{
Console.WriteLine("Scanning...");
}
}
public class SomeBasicPrinter : Printer
{
public override void Print()
{
Console.WriteLine("Printing...");
}
}
Technically, there could be an edge-case (should be uncommon!) where a deriving class doesn't need to implement all the methods, in such a case I'd rather it to override and throw an error to signal the user that this method should not be used.
That said, in the provided example there is only one method, so the question is: if a derived class doesn't need this method - why do you need to inherit the abstract class to begin with? if it's just in order to provide an example that's understandable - but better improve the example to include other methods that are used in the derived class.
I have a class I am unit testing and all I want to do is to verify that the public setter gets called on the property. Any ideas on how to do this?
I don't want to check that a value was set to prove that it was called. I only want to ensure that the constructor is using the public setter . Note that this property data type is a primitive string
This is not the sort of scenario that mocking is designed for because you are trying to test an implementation detail. Now if this property was on a different class that the original class accessed via an interface, you would mock that interface and set an expectation with the IgnoreArguments syntax:
public interface IMyInterface
{
string MyString { get; set; }
}
public class MyClass
{
public MyClass(IMyInterface argument)
{
argument.MyString = "foo";
}
}
[TestClass]
public class Tests
{
[TestMethod]
public void Test()
{
var mock = MockRepository.GenerateMock<IMyInterface>();
mock.Expect(m => m.MyString = "anything").IgnoreArguments();
new MyClass(mock);
mock.VerifyAllExpectations();
}
}
There are 2 problems with what you are trying to do. The first is that you are trying to mock a concrete class, so you can only set expectations if the properties are virtual.
The second problem is the fact that the event that you want to test occurs in the constructor, and therefore occurs when you create the mock, and so occurs before you can set any expectations.
If the class is not sealed, and the property is virtual, you can test this without mocks by creating your own derived class to test with such as this:
public class RealClass
{
public virtual string RealString { get; set; }
public RealClass()
{
RealString = "blah";
}
}
[TestClass]
public class Tests
{
private class MockClass : RealClass
{
public bool WasStringSet;
public override string RealString
{
set { WasStringSet = true; }
}
}
[TestMethod]
public void Test()
{
MockClass mockClass = new MockClass();
Assert.IsTrue(mockClass.WasStringSet);
}
}
I'm writing an Ocean plugin for Petrel and need to persist some custom domain objects, and everything seems to point to using a structured archive data source. I've created a common class to hold a lot of the standard domain object stuff (droid, name, color, image, comments, history, etc), to avoid rewriting it for every domain object I create. The Ocean development guide only has simple examples of classes with no inheritance, but given that everything has a version number, I foresee a potential problem when the base class version is different than the version of inherited-class-1 which is different than inherited-class-2, and then I update something in the base class.
Is it possible to use a structured archive with the common base class? Are there any special considerations for versioning, or anything else I need to be aware of?
ETA: A simple class diagram showing the relationships and some stuff I've tried
public abstract class ClassA
|
-----------------------------------
| |
public class ClassB : ClassA public classC : ClassA
public class ClassD
{
private List<ClassA> _myClassAObjects;
}
All classes are marked Archivable, and in ClassD, _myClassAObjects is marked Archived. Everything saves OK, but when I load, I get an InvalidCastException, as it tries to cast the List<ClassB> to a List<ClassA>. The casting should work, since ClassB inherits from ClassA, should it not?
Got an answer from Schlumberger. It is possible, by doing something like this:
[Archivable]
public abstract class Abstract CDO
{
[ArchivableContextInject]
protected StructuredArchiveDataSource DataSourceCore;
[Archived(Name = "Name")]
private string _name;
private AbstractCDO _parent;
[Archived(Name="ParentDroid")]
private Droid _parentDroid;
[Archived(Name = "Droid")]
protected Droid DroidCore
{
get { return _droid; }
set
{
if (_droid != value)
{
DataSourceCore.IsDirty = true;
_droid = value;
}
}
}
public Droid ParentDroid
{
get { return _parentDroid; }
set
{
if (_parentDroid != value)
{
DataSourceCore.IsDirty = true;
_parentDroid = value;
}
}
}
public AbstractCDO Parent
{
get { return _parent; }
set
{
if (_parent != value)
{
DataSourceCore.IsDirty = true;
_parent = value;
_parentDroid = _parent.Droid;
}
}
}
protected AbstractCDO(string name)
{
_name = name;
DataSourceCore = Factory.Get();
_droid = DataSourceCore.GenerateDroid();
DataSourceCore.AddItem(_droid, this);
}
}
[Archivable]
public abstract class AbstractCDOCollection : AbstractCDO, IObservableElementList
{
[Archived]
private List<AbstractCDO> _children;
protected AbstractCDO(string name) : base(name) { }
public List<AbstractCDO> Children
{
get { return _children; }
}
}
[Archivable]
public class ConcreteObject : AbstractCDO
{
public ConcreteObject(string name) : base(name)
{
// other stuff
}
}
The DataSource property needs to be protected since the injection had a bug which was fixed in Petrel 2013.3 / 2014.1.
I wonder how to add state to the chain of decorators that will be available to the consumer. Given this simplified model:
abstract class AbstractPizza
{
public abstract print(...);
}
class Pizza : AbstractPizza
{
public int Size { get; set; }
public print(...);
}
abstract class AbstractPizzaDecorator
{
public Pizza:AbstractPizza;
public abstract print();
}
class HotPizzaDecorator : AbstractPizzaDecorator
{
public int Hotness { get; set; }
public print(...);
}
class CheesyPizzaDecorator : AbstractPizzaDecorator
{
public string Cheese { get; set; }
public print(...);
}
void Main()
{
BigPizza = new Pizza();
BigPizza.Size = 36;
HotBigPizza = new HotPizzaDecorator();
HotBigPizza.Pizza = BigPizza;
HotBigPizza.Hotness = 3;
HotBigCheesyPizza = new CheesyPizzaDecorator();
HotBigCheesyPizza.Pizza = HotBigPizza;
HotBigCheesyPizza.Cheese = "Blue";
HotBigCheesyPizza.print();
HotBigCheesyPizza.size = 28; // ERRRRRR !
}
Now if they all implement the print method and propagate that though the chain, it's all good. But how does that work for the state? I can't access the size property on the HotBigCheesyPizza.
What's the part that I'm missing? Wrong pattern?
Thanks for helping!
Cheers
The decorator pattern is for adding additional behavior to the decorated class without the client needing to adjust. Thus it is not intended for adding a new interface (e.g. hotness, cheese) to the thing being decorated.
A somewhat bad example of what it might be used for is where you want to change how size is calculated: you could create a MetricSizePizzaDecorator that converts the size to/from English/metric units. The client would not know the pizza has been decorated - it just calls getSize() and does whatever it needs to do with the result (for example, to calculate the price).
I would probably not use the decorator in my example, but the point is: it does not alter the interface. In fact, nearly all design patterns come down to that - adding variability to a design without changing interfaces.
one way of adding state is by using a self referential data structure (a list). but this uses the visitor pattern and does more than you probably want. this code is rewritten from A little Java, a few patterns
// a self referential data structure with different types of nodes
abstract class Pie
{
abstract Object accept(PieVisitor ask);
}
class Bottom extends Pie
{
Object accept(PieVisitor ask) { return ask.forBottom(this); }
public String toString() { return "crust"; }
}
class Topping extends Pie
{
Object topping;
Pie rest;
Topping(Object topping,Pie rest) { this.topping=topping; this.rest=rest; }
Object accept(PieVisitor ask) { return ask.forTopping(this); }
public String toString() { return topping+" "+rest.toString(); }
}
//a class to manage the data structure
interface PieManager
{
int addTopping(Object t);
int removeTopping(Object t);
int substituteTopping(Object n,Object o);
int occursTopping(Object o);
}
class APieManager implements PieManager
{
Pie p=new Bottom();
// note: any object that implements a rational version of equal() will work
public int addTopping(Object t)
{
p=new Topping(t,p);
return occursTopping(t);
}
public int removeTopping(Object t)
{
p=(Pie)p.accept(new RemoveVisitor(t));
return occursTopping(t);
}
public int substituteTopping(Object n,Object o)
{
p=(Pie)p.accept(new SubstituteVisitor(n,o));
return occursTopping(n);
}
public int occursTopping(Object o)
{
return ((Integer)p.accept(new OccursVisitor(o))).intValue();
}
public String toString() { return p.toString(); }
}
//these are the visitors
interface PieVisitor
{
Object forBottom(Bottom that);
Object forTopping(Topping that);
}
class OccursVisitor implements PieVisitor
{
Object a;
OccursVisitor(Object a) { this.a=a; }
public Object forBottom(Bottom that) { return new Integer(0); }
public Object forTopping(Topping that)
{
if(that.topping.equals(a))
return new Integer(((Integer)(that.rest.accept(this))).intValue()+1);
else return that.rest.accept(this);
}
}
class SubstituteVisitor implements PieVisitor
{
Object n,o;
SubstituteVisitor(Object n,Object o) { this.n=n; this.o=o; }
public Object forBottom(Bottom that) { return that; }
public Object forTopping(Topping that)
{
if(o.equals(that.topping))
that.topping=n;
that.rest.accept(this);
return that;
}
}
class RemoveVisitor implements PieVisitor
{
Object o;
RemoveVisitor(Object o) { this.o=o; }
public Object forBottom(Bottom that) { return new Bottom(); }
public Object forTopping(Topping that)
{
if(o.equals(that.topping))
return that.rest.accept(this);
else return new Topping(that.topping,(Pie)that.rest.accept(this));
}
}
public class TestVisitor
{
public static void main(String[] args)
{
// make a PieManager
PieManager pieManager=new APieManager();
// add some toppings
pieManager.addTopping(new Float(1.2));
pieManager.addTopping(new String("cheese"));
pieManager.addTopping(new String("onions"));
pieManager.addTopping(new String("cheese"));
pieManager.addTopping(new String("onions"));
pieManager.addTopping(new String("peperoni"));
System.out.println("pieManager="+pieManager);
// substitute anchovies for onions
int n=pieManager.substituteTopping(new String("anchovies"),new String("onions"));
System.out.println(n+" pieManager="+pieManager);
// remove the 1.2's
n=pieManager.removeTopping(new Float(1.2));
System.out.println(n+" pieManager="+pieManager);
// how many anchovies do we have?
System.out.println(pieManager.occursTopping(new String("anchovies"))+" anchovies");
}
}
I believe your component Pizza and your abstract decorator PizzaDecorator are supposed to share the same interface, that way each instance of the decorator is capable of the same operations as the core component Pizza.
I have multiple classes that have similar implementation for different named methods:
class MyClassX
{
public int MyClassXIntMethod(){}
public string MyClassXStringMethod(){}
}
class MyClassY
{
public int MyClassYIntMethod(){}
public string MyClassYStringMethod(){}
}
the methods inside the classes have similar implementation but because the method's names are different (due to 3rd party constraints) i cannot use inheritance.
I'm looking for an elegant solution that would be better than implementing the same functionality over and over again.
The classic answer IMHO is use the adpater pattern for every 3rd party calling party.
Don't apply blindly but see if it is a good fit first.
class MyClassXAdapter
{
IMyInterface _myImpClass
public int MyClassXIntMethod(){ return _myImpClass.IntMethod()}
public string MyClassXStringMethod(){ return _myImpClass.StringMethod() }
}
class MyClassYAdapter
{
IMyInterface _myImpClass
public int MyClassYIntMethod(){ return _myImpClass.IntMethod()}
public string MyClassYStringMethod(){ _myImpClass.StringMethod() }
}
class MyClassImplementation :IMyInterface
{
public int IntMethod(){}
public string StringMethod(){}
}
And whats the problem in using composition?
class MyClassY
{
private MyClassX myclx;
public int MyClassYIntMethod()
{
return myclx.MyClassXIntMethod();
}
public string MyClassYStringMethod(){...Similarly here...}
}
Why not simply create a common super class, and let each "MyClass_" call that common function? You can have a different program signature and still reuse the same codes pieces. Without copy and paste the same code again.
class MyClassX extends MyClassGeneric
{
public int MyClassXIntMethod(){}
public string MyClassXStringMethod(){}
}
class MyClassY extends MyClassGeneric
{
public int MyClassYIntMethod(){ return MyClassIntMethod();}
public string MyClassYStringMethod(){return MyClassStringMethod();}
}
class MyClassGeneric
{
protected int MyClassIntMethod(){ /*...... logic .....*/ return 0; }
protected string MyClassStringMethod(){/*...... logic ....*/return "";}
}
Real world example.
Without "software patternitis". (I apply software patterns, very useful, but, I'm not adicted to them).
collections.hpp
#define pointer void*
class Collection {
protected:
VIRTUAL bool isEmpty();
VIRTUAL void Clear();
}
class ArrayBasedCollection: public Collection {
protected:
int internalInsertFirst(pointer Item);
int internalInsertLast(pointer Item);
pointer internalExtractFirst(int Index);
pointer internalExtractLast(int Index);
}
class Stack: public ArrayBasedCollection {
public:
OVERLOADED bool isEmpty();
OVERLOADED void Clear();
// calls protected "internalInsertFirt"
void Push(pointer Item);
// calls protected "internalExtractLast"
pointer Pop(pointer Item);
}
class Queue: public ArrayBasedCollection {
public:
OVERLOADED bool isEmpty();
OVERLOADED void Clear();
// calls protected "internalInsertFirt"
void Push(pointer Item);
// calls protected "internalExtractFirst"
pointer Pop(pointer Item);
}
Cheers.