Liskov Substitution Principle Violation Rules - solid-principles

The purpose of inheritance is to inherit and extend.
So my question is that if child class have more method that will it break the LSP ?
So in my example I have 2 classes Rectangle and Square. Square is child of Rectangle. Now both have 2 different methods HelloRectangle and HelloSquare. So will it breack LSP or not ?
public class Rectangle
{
//public int Width { get; set; }
//public int Height { get; set; }
public virtual int Width { get; set; }
public virtual int Height { get; set; }
public Rectangle()
{
}
public Rectangle(int width, int height)
{
Width = width;
Height = height;
}
public override string ToString()
{
return $"{nameof(Width)}: {Width}, {nameof(Height)}: {Height}";
}
public string HelloRectangle()
{
return "Hello Rectangle";
}
}
public class Square : Rectangle
{
public override int Width // nasty side effects
{
set { base.Width = base.Height = value; }
}
public override int Height
{
set { base.Width = base.Height = value; }
}
public string HelloSquare()
{
return "Hello Square";
}
}

child class have more method that will it break the LSP ? :- Not it will not break LSP unless you change the behavior of common method. When you substitute child class then you can only access method which drive from base regardless of more/other methods in child class for example
Public class A
{
public int sum ()
{
}
}
public class B
{
public int sum ()
{
// same behaviour as per method in A
}
public int divide()
{
}
}
// So calling of method
B b = new B();
b.Sum();
//So If you substitute with drive class then
B b = new A();
// Here in the below line there is no impact of other methods of child class Thus child class have more method will not break the LSP
b.Sum();
Hence both have 2 different methods HelloRectangle and HelloSquare. So it will not break LSP.
But on other hand setwidth and setheight break LSP because in case of square, behavior of setwidth and setheight has been changed
I hope you got the answer and not confused with setwidth and setheight method in your case.

The substitutability defined by the LSP applies in only one direction: a child may replace its parent. It is never the case that a parent is expected to replace its child, irrespective of the LSP.
In statically-typed languages, substitution is only possible in one direction. For example, in Java we can show that substitution only compiles when Child replaces Parent.
class Parent {
void method() {
System.out.println("Hello Parent");
}
}
class Child extends Parent {
void anotherMethod() {
System.out.println("Hello Child");
}
}
class Main {
public static void main(String... args) {
Parent parent = new Parent();
Child child = new Child();
useParent(child); // compiles: Child is syntactically substitutable for Parent
useChild(parent); // error: Parent is not syntactically substitutable for Child.
}
static void useParent(Parent parent) {
parent.method();
}
static void useChild(Child child) {
child.anotherMethod();
}
}
It's not a problem that Child has anotherMethod(), because Child cannot be replaced by Parent.

Related

SOLID priciples - Single Responsible is just about composition or also dependency inversion?

I have seen examples online about the Single Responsible principle.
They always use IoC/DI as an example.
They move the code from class A to class B and pass class B as reference.
See code below:
class B {}
class A {
b;
// reference used
constructor(b) {
this.b = b;
}
doStuff() {
...
this.b.doSomeOtherStuff();
}
}
But the Single Responsible principle is about to increase the coherence.
Theoretically the code above would also follow the Single Reponsible principle without
passing down a reference to class B, right?
Like this:
class B {}
class A {
// no reference
constructor() {
this.b = new B;
}
doStuff() {
...
this.b.doSomeOtherStuff();
}
}
In the book Clean Code by Robert C. Martin there is an example reagarding the SRP where he uses only composition.
So I would say yes, Singe Responsible Priciple is valid without IoC/DI.
In the example below hes directly creating an instance of the LinkedList.
public class Stack {
private int topOfStack = 0;
// creating a direct instance here
List < Integer > elements = new LinkedList < Integer > ();
public int size() {
return topOfStack;
}
public void push(int element) {
topOfStack++;
elements.add(element);
}
public int pop() throws PoppedWhenEmpty {
if (topOfStack == 0)
throw new PoppedWhenEmpty();
int element = elements.get(--topOfStack);
elements.remove(topOfStack);
return element;
}
}

How to deserialize an object with type info outside himself

I have a Parent type with one of its fields is a Discriminated Union (JsonSubTypes).In my example below i keep the Discriminant (id) inside my child field.
What i want to know is : is it possible to have the discriminant outside my child object and directly in the parent ?
What works
public class Parent{
Child childField{get;set;}
}
[JsonConverter(typeof(JsonSubTypes),CHILDTYPE)]
[JsonSubTypes.KnownSubTypes(typeof(Child1),CTYPE.Child1)]
[JsonSubTypes.KnownSubTypes(typeof(Child2),CTYPE.Child2)]
public abstract class Child{
public enum Discriminator{
Child1=0,
Child2=1
}
private const string CHILDTYPE="childType";
[JsonProperty(CHILDTYPE)]
public abstract Discriminator Kind{get;} //i want this moved to parent
}
public class Child1:Child{
public int Value{get;set;}
public override Kind=>Discriminator.Child1;
}
public class Child2:Child{
public bool Value{get;set;}
public override Kind=>Discriminator.Child2;
}
Usage
List<Parent>parents=new List<Parent>{new Child1{Value=3},new Child2{Value=True}};
var str=JsonConvert.SerializeObject(parents);
List<Parent>parents=JsonConvert.DeserializeObject<List<Parent>(str);
What i want
public class Parent{
private const string CHILDTYPE="childType";
public enum Discriminator{
Child1=0,
Child2=1
}
public abstract Discriminator Kind{get;}
Child childField{get;set;}
}
[JsonConverter(typeof(JsonSubTypes),CHILDTYPE)]
[JsonSubTypes.KnownSubTypes(typeof(Child1),CTYPE.Child1)]
[JsonSubTypes.KnownSubTypes(typeof(Child2),CTYPE.Child2)]
public abstract class Child
{
}
As you can see what i want is to move my Kind field from the Child and into the Parent.Can i somehow accomplish this? I want to keep everything the same , just instead of a Json like this:
{
childField:{ Kind:3}
}
I need to accomodate for a json like this:
{
Kind:3
childField:{}
}
Can i accomplish this ? Can i somehow decorate the parent to know to deserialize one of its fields based on another ?

How to use this before super?

I know that this is not allowed before super but I need to do it. I was wondering if there was a legal way to do this in es6?
My code:
class DOMElement {
constructor(aNodeName) {
this.name = aNodeName;
this.create();
}
create() {
let domref = document.createElement(this.name);
document.body.appendChild(domref);
return domref;
}
}
class Button extends DOMElement {
constructor(aLabel) {
this.label = aLabel;
super('button');
}
create() {
let domref = super.create();
domref.textContent = this.label;
}
}
If I don't set this.label before calling super('button') in Button.prototype.create then domref.textContent is set to undefined.
There's no 'legal' way.
It can be be a getter in cases where static property value is supposed to be used by parent class on construction:
get label() {
return 'label';
}
In this case this means that class design is just wrong. There's nothing in parent class that would impose such restriction. Actually, label is only used by child class. It should be:
constructor(aLabel) {
super('button');
this._domref.textContent = alabel;
}
create() {
// if parent class is user-defined, it should be done there
// instead of returning a value, because it doesn't make sense
// to leave an important part of the object without a reference
this._domref = super.create();
}

How to Override Constants in ActionScript 3

I have the two following classes:
public class Parent{
static internal const _name:String = "Parent";
public function get name():String{
return _name;
}
}
public class Child{
static internal const _name:String = "Child";
}
If I create an instance of class Child and call its name() getter, since it will call the name() method it inherits from Parent, it returns "Parent". I could, of course, override the name() method:
public class Child{
static internal const _name:String = "Child";
override public function get name():String{
return _name;
}
}
That returns "Child". However, it seems silly to have to copy the exact same code of the method from the parent. Is there any simpler way to do this?
I would take a different approach by making the "name" property a requirement for the parent's constructor:
public class Parent
{
static internal var _name : String;
public function Parent(name : String = "Parent") {
_name = name;
}
public function get name() : String {
return _name;
}
}
Child Class:
public class Child extends Parent
{
public function Child() {
super("Child");
}
}
Firstly, you cannot override static methods or properties - they are not inherited, so no override for them.
Secondly, if you declared a constant to be of a complex type, it is not really a constant. I.e. if it is an object, then you can change its keys / values, if it is an array, you can add / remove members and so on.
But the desire to make this functionality more generic is understandable. So, what I'd do:
Have some property outside both parent and child, let say in class X, or package Y. Let it be package Y. So, you'd create a dictionary in package Y, let it be Y.names and in your name getter you'd do:
import Y.names;
. . .
public function get name() {
return names[(this as Object).constructor];
}
your names variable would be:
package Y {
public var names:Dictionary = generateNames();
internal function generateNames():Dictionary {
var result:Dictionary = new Dictionary();
result[ChildClass] = "child";
result[ParentClass] = "parent";
. . .
return result;
}
}
This way it would be sufficient to only implement name getter in super-class, and all inheriting classes will be able to use super-class code as is, no need to change anything. However, this means that some (maybe important) information pertaining to this class will be stored elsewhere (may be difficult to find, this is not the common way people program in AS3).
your implementation of get name should look like this, then the getter is one and each of the new classes needs to have it's own public static var _name defined:
//in the base class
public function get name():String
{
var _sName:String;
if ((this as Object).constructor._name)
{
_sName = (this as Object).constructor._name;
}
else
{
try
{
var o:Object = getSuperClass(this);
while (o)
{
if (o._name)
{
_sName = o._name;
break;
}
o = getSuperClass(o);
}
}
catch (e:*)
{}
}
return _sName;
}
//as found here: http://www.actionscriptdeveloper.co.uk/getting-the-class-of-an-object-in-as3/
public static function getSuperClass(o: Object): Object
{
var n: String = getQualifiedSuperclassName(o);
if (n == null)
return(null);
return getDefinitionByName(n);
}
the static members can be accessed only via class reference which we can get from constructor object, "this" will point to the current class in the inheritance chain so you can call this in parent class and it will point to a Child in a Child class.
[EDIT]
I've modified it so it tests for existance of the public static property _name if not found on "this" instance then in a loop the parent class is checked until one is found - like inheritance:)
I'm using this feature to create clone method: constructor as helper in clone method implementation
best regards
Why don't you store such a constant within a corresponding function instead of declaring an inaccessible constant?
class Parent {
...
public function get name():String { return 'Parent'; }
}
class Child extends Parent {
...
override public function get name():String { return 'Child'; }
}
By the way, if your Parent class is a descendant of DisplayObject, you should be careful with name property, as it's needed sometimes by operating code, e.g. getChildByName().
I have found something that seems to work. Any feedback is greatly appreciated:
public class Parent{
prototype._name = "Parent";
public function get name():String{
return this["_name"];
}
}
public class Child{
prototype._name = "Child";
}

Overriding x, y, width and height (getters)

Is there a way to override the width (for a getter) on a Sprite?
I see examples of how to override the setter but not the getter
I need to do something like
override public function get width():Number {
if (onecase) {
return this width;
} else {
return another width;
}
}
Yes you can.
override public function get width():Number {
if (onecase) {
return myWidth;
} else {
return super.width;
}
}
super.width is will be basic Sprite getter.
the setter/getter method signatures need to be identical since ActionScript 3.0 doesn't support function overloading. the x, y, width and height properties of display objects are Number objects, not int as one might assume.
//Class Properties
private var widthProperty:Number;
~
//Set Width
override public function set width(value:Number):void
{
widthProperty = value;
}
//Get Width
override public function get width():Number
{
return widthProperty;
}