I am currently in the design mode for this problem:
Implement the Speaker interface that is predefined. Create three classes that implement Speaker in various ways. Create a driver class whose main method instantiates some of these objects and tests their abilities.
How would I go about designing this program and them moving into the coding stage. I want to use these three classes to implement the Speaker interface class: Politician, Lecturer, and Pastor class. The methods I want to use are:
public void speak();
public void announce (String str);
Now for my design and coding, how would I go about to declare and object reference variable and have that variable have multiple references?
It's simple really. In brief:
class ClassA implements Speaker
{
public void speak(){
System.out.println("I love Java") ; //implement the speak method
}
}
class ClassB implements Speaker //follow the example of ClassA
class ClassC implements Speaker //same as above
Speaker[] speakers = new Speakers{new ClassA(),new ClassB(),new ClassC()} ;
for(Speaker speaker: speakers)
speaker.speak(); //polymorphically call the speak() method defined in the contract.
See "What is an Interface?" http://docs.oracle.com/javase/tutorial/java/concepts/interface.html This will hopefully get you started with the basics you're looking for.
The start of the implementation would look something like the following...
class Politician implements Speaker
{
public void speak()
{
// Method implementation
}
public void announce (String str)
{
// Method implementation
}
}
class Lecturer implements Speaker
{
public void speak()
{
// Method implementation
}
public void announce (String str)
{
// Method implementation
}
}
class Lecturer implements Speaker
{
public void speak()
{
// Method implementation
}
public void announce (String str)
{
// Method implementation
}
}
public static void main(String [] args)
{
Speaker s1 = new Politician();
Speaker s2 = new Pastor();
Speaker s3 = new Lecturer();
// Do something...
}
Use a Factory Method Design Pattern.. Check this article at http://en.wikipedia.org/wiki/Factory_method_pattern
Your code could look something like this, if you use the Factory pattern
public class SpeakerFactory {
enum SpeakerEnum { POLITICIAN, LECTURER, PASTOR} ;
Speaker getSpeaker(SpeakerEnum speakerType) {
switch (speakerType) {
case POLITICIAN : return new Politician();
....
}
}
}
Related
I'm trying to apply the decorator pattern to making an object that encrypts a word into a certain encryption, like the L337 method, which replaces letters like 9 with g, or 4 with r. Basically, I want to type a word into an inputfield and show the encrypted word in a text object. But I can't get the L337 decorator to inherit from the main decorator class. It won't accept the keyword 'super', so I tried the base word, but then when I implement Encrypt, it won't take the object newEncryption. Could someone help me figure out how to put this pattern together please?
I basically know what the decorator pattern is. It's making an object, making a basic decorator, and making a specific decorator, and instantiating the object with the decorating for exclusive methods and features.
public class Encryption : MonoBehaviour
{
public static InputField inputBox;
public static Text outputText;
public interface IEncryption { void Encrypt(); }
public class TextEncryption : IEncryption
{
public void Encrypt()
{
string currentText = inputBox.text;
outputText.text = currentText;
}
}
public abstract class encryptionDecorator : IEncryption
{
protected IEncryption tempEncryption;
public encryptionDecorator(IEncryption newEncryption)
{
tempEncryption = newEncryption;
}
public void Encrypt()
{
tempEncryption.Encrypt();
}
}
public class L337EncryptionDecorator : encryptionDecorator
{
public L337EncryptionDecorator(IEncryption newEncryption) : base(newEncryption)
{
print("Encrypting L337 Code");
}
public void Encrypt()
{
}
}
}
I think you actually want to use tempEncryption, but you didnt really tell where you could not use newEncryption so im guessing.
But anyway, I hope this will clear some things up. Its slightly edited from your code so I didnt need to put GUI stuff, but you could just CnP it to unity.
using UnityEngine;
public class Encryption : MonoBehaviour {
public interface IEncryption {
void Encrypt();
}
public class TextEncryption : IEncryption {
public void Encrypt() {
}
}
public abstract class EncryptionDecorator : IEncryption {
protected IEncryption tempEncryption;
public EncryptionDecorator(IEncryption newEncryption) {
//this will be called when you override the constructor
Debug.Log("In EncryptionDecorator constructor: " + newEncryption.GetType());
tempEncryption = newEncryption;
}
//if you are going to override a method in a child class,
//declare it either abstract ("no body; passes implementation to child") or
//virtual ("allows for a base implementation")
public virtual void Encrypt() {
Debug.Log("In EncryptionDecorator.Encrypt(): " + tempEncryption.GetType());
tempEncryption.Encrypt();
}
}
public class L337EncryptionDecorator : EncryptionDecorator {
public L337EncryptionDecorator(IEncryption newEncryption) : base(newEncryption) {
//newEncryption is a parameter, think of it as sort of a local variable.
//but since you pass it down to the parent class, it gets assigned to tempEncryption
//the base-class constructor is called first!
Debug.Log("In L337EncryptionDecorator constructor: " + newEncryption.GetType());
}
//this overrides the base implementation. you can call it with
//base.Encrypt() though.
public override void Encrypt() {
//you have no parameters here, but you could use the inherited variable tempEncryption because you declared it protected
Debug.Log("In L337EncrytionDecorator.Encrypt(): " + tempEncryption.GetType());
//base refers to the base class
base.Encrypt();
}
}
void Start() {
IEncryption encryption = new L337EncryptionDecorator(new TextEncryption());
encryption.Encrypt();
}
}
or maybe i missed what this is all about?!
I come from a Python background and in Python you can pass in the type of an object as a parameter. But in Java you cannot do this, any tips on how to get something like this working?
private void function(Type TypeGoesHere)
Stock s = new TypeGoesHere();
s.analyze();
}
Java does not support Python’s way of referencing functions and classes. To achieve this behaviour, you have to use two advanced techniques: generics and reflection. Explaining these concepts is beyond the scope of a SO answer. You should read a Java guide to learn about them.
Yet here is an example how this would look like, assuming that the given class has a no-argument constructor:
public <T extends Stock> void analyzeNewStock(Class<T> clazz) throws Exception {
Stock s = clazz.newInstance();
s.analyze();
}
Then call this function with analyzeNewStock(MyStock.class).
As this is a rather complicated and error-prone approach, you’d rather define an interface that creates Stock instances:
public interface StockProvider {
Stock createStock(String value);
}
public class MyStockProvider implements StockProvider {
private final String valueTwo;
public MyStockProvider(String valueTwo) {
this.valueTwo = valueTwo;
}
#Override
public Stock createStock(String valueOne) {
return new MyStock(valueOne, valueTwo);
}
}
public class MyOtherClass {
public void analyzeNewStock(StockProvider provider) {
provider.createStock("Hi!").analyze();
}
public static void main(String[] args) {
analyzeNewStock(new MyStockProvider("Hey!"));
}
}
In Java you can pass a Class. You can do it like this:
private void function(Class c)
This is not very common procatice though. You can probably get wha you need by looking into Strategy pattern, or proper use of Object Oriented Programming (polymorphism).
If you are looking for a way to build some objects, look into Factory pattern.
If you want to create a generic class- look into this detailed answer: https://stackoverflow.com/a/1090488/1611957
You could use generics. For example:
private <T> void function(Class<T> clazz) {
try{
T t = clazz.newInstance();
//more code here
}catch(InstantiationException | IllegalAccessException ex){
ex.printStackTrace();
}
}
The Class<T> clazz shows what type to instantiate. The try/catch is just to prevent errors from stopping your code. The same idea is expanded in this SO post. More info here.
However, I'm not really sure why you would want to do this. There should easily be a workaround using a simple interface. Since you already know that you want an object with type Stock, you could pass an implementation of the interface. For example:
//interface to implement
public interface Stock {
public void analyze();
}
//rewrite of function
private void function(Stock s){
s.analyze();
}
And using two ways to call function:
//first way
public class XYZ implements Stock{
public void analyze(){
//some code here
}
}
//calling the function
function(new XYZ());
//second way
function(new Stock(){
public void analyze(){
//your code here
}
});
Encapsulation is said to be wrapping up of data and method and hidding functionality(method and instance variable) that is not needed for outside of this object
my question is only making a variable private and public is encapsulation ? or making a class with abstraction is also encapsulation ?
For Example:
I have Switch(Electic Switch) class doing on or off
to make a Switch class i have used abstraction
and i encapsulated Switch class with using abstraction so that i can map
motor or bulb or any electric Instrument
public class Switch {
private boolean isOff = true;
private ISwitchListener listener;
public Switch(ISwitchListener listener) {
this.listener = listener;
}
public void trigger() {
isOff = !isOff;
if(isOff) {
listener.off();
} else {
listener.on();
}
}
}
public class Bulb implements ISwitchListener {
#Override
public void on() {
// TODO Auto-generated method stub
System.out.println("bulb is glittering");
}
#Override
public void off() {
// TODO Auto-generated method stub
System.out.println("bulb is not glittering");
}
}
public interface ISwitchListener {
public void on();
public void off();
}
public class Executor {
public static void main(String[] args) {
// TODO Auto-generated method stub
Switch swt = new Switch(new Bulb());
swt.trigger();
}
}
if i am not using abstraction here , i would have class like below
public class Switch {
private boolean isOff = true;
public void trigger() {
isOff = !isOff;
Bulb b =new Bulb();
if(isOff) {
b.off();
} else {
b.on();
}
}
}
When i want to map Motor to Switch i need to change class as bleow
public class Switch {
private boolean isOff = true;
public void trigger() {
isOff = !isOff;
Bulb b =new Bulb();
if(isOff) {
b.off();
} else {
b.on();
}
}
}
public class Motor {
public void on() {
// TODO Auto-generated method stub
System.out.println("Motor is rotating");
}
public void off() {
// TODO Auto-generated method stub
System.out.println("Motor is getting off to rotate");
}
}
In general, no, abstraction and encapsulation are two different things. Specifically, abstraction means removing detail that is unnecessary for the intended purpose of the code or model. For example, if you write a program to calculate how much paint you need for a house, your model of a house needs to include the surface area, but doesn't need to include the address, or the size of the yard.
Encapsulation means hiding the internal workings of an object or module, such that the coupling between objects can be controlled and readily changed. If there were no encapsulation, clients of the object might directly reference its internal elements, which would mean that you would have to change all the clients if you modified the object.
Regarding the code example, I think a better solution would be to create an interface "Switchable" and have Motor and Bulb implement it. Like so:
public interface Switchable {
void on();
void off();
}
public class Motor implements Switchable {
public void on() {
System.out.println("Motor is rotating");
}
public void off() {
System.out.println("Motor is getting off to rotate");
}
}
public class Switch {
private boolean isOff = true;
private Switchable switchable;
public Switch(Switchable switchable) {
this.switchable = switchable;
}
public void trigger() {
isOff = !isOff;
if(isOff) {
switchable.off();
} else {
switchable.on();
}
}
}
Hope that helps.
Your first example is an example for dependency injection => you let the caller decide which concrete class the class "Switch" needs to do its job.
In fact it is the "opposite" of data hiding as the outside world has to know some implementation details of the class "Switch". => it needs an implementation of ISwitchListener
As #T I said, it can be a method hiding for example from Java 8 you can create default implementation in the interface, so you can hide that in the class where implement the interface.
But encapsulation is about field (instance variable) hiding. Creating a private member (instance variable) and creating setter and getter. You will reach the value only via dedicated methods.
If you want to encapsulate your methods, you need to deal with accessibility (see default and protected modifiers).
So the answer for your question is: No. Making a class with abstraction is not encapsulation.
Abstraction and Encapsulation are interrelated. You can say Abstraction is needed to Encapsulate the system.
Abstraction is when a client system does not need to know more than what is in the interface.
Encapsulation is when a client of a module is not able to know more than what is in the interface.
Pleas refer this page for a beautiful article on this topic.
I have the below code.
public class Test {
public static void main(String args[])
{
int i = 0;
if(i==0){
Beer obj = new Beer();
}
else {
Rum obj = new Rum();
}
System.out.println(obj.brand); //doesn't work
} }
class Drink {
}
class Beer extends Drink{
public String brand = "BeerBrand"; }
class Rum extends Drink{
public String brand = "RumBrand"; }
Is there an way to make the above work without using function overriding or dynamic class loading?
All classes are dynamically loaded in JVM there is no static loading like in C. Is this correct?
Drink should be an abstract class and provide an abstract member getBrand() or similar, overridden by Beer and Rum.
Then you'd do something like:
Drink d = null;
if (...) {
d = new Beer();
}
so you instantiate the reference appropriately. Because it's still of type Drink you can reference the brand. The Drink reference will let you access anything drink-able, and the implementation provides the specifics. Note that Drink is abstract, since you can't instantiate a Drink - you have to be more specific.
To answer your further questions, you could provide a base method and do something like:
if (this instanceof Beer) {
...
}
to avoid overriding. But why would you ?
To answer your second question, classes are dynamically loaded by the JVM upon reference. You can watch that occur by setting the -verbose flag on the JVM.
This code won't work because scope of 'obj' is only within if-else block.
You need to declare it above if-else block of type Drink.
Is there an way to make the above work without using function overriding or dynamic class loading?
The only alternative is to use reflections, but fixing the design of the classes would be much simpler/better
All classes are dynamically loaded in JVM there is no static loading like in C. Is this correct?
Yes. They can be dynamically loaded more than once and even unloaded.
Using an object orientated approach would look like this.
public class Test {
public static void main(String... args) {
Drink drink;
if (args.length == 0) {
drink = new Beer();
} else {
drink = new Rum();
}
System.out.println(drink.getBrand());
}
}
interface Drink {
public String getBrand();
}
class Beer implements Drink {
#Override
public String getBrand() {
return "BeerBrand";
}
}
class Rum implements Drink {
#Override
public String getBrand() {
return "RumBrand";
}
}
So, in a single parent inheritance model what's the best solution for making code extensible for future changes while keeping the same interface (I'd like to emphasize the fact that these changes cannot be known at the time of the original implementation, the main focus of my question is to explore the best mechanism/pattern for supporting these changes as they come up)? I know that this is a very basic OO question and below I provide example of how I've been going about it, but I was wondering if there a better solution to this common problem.
Here's what I've been doing (the example code is in Java):
In the beginning, the following two classes and interface are created:
public class Foo
{
protected int z;
}
public interface FooHandler
{
void handleFoo(Foo foo);
}
public class DefaultFooHandler implements FooHandler
{
#Override
public void handleFoo(Foo foo)
{
//do something here
}
}
The system uses variables/fields of type FooHandler only and that object (in this case DefaultFooHandler) is created in a few, well-defined places (perhaps there's a FooHandlerFactory) so as to compensate for any changes that might happen in the future.
Then, at some point in the future a need to extend Foo arises to add some functionality. So, two new classes are created:
public class ImprovedFoo extends Foo
{
protected double k;
}
public class ImprovedFooHandler extends DefaultFooHandler
{
#Override
public void handleFoo(Foo foo)
{
if(foo instanceof ImprovedFoo)
{
handleImprovedFoo((ImprovedFoo)foo);
return;
}
if(foo instanceof Foo)
{
super.handleFoo(foo);
return;
}
}
public void handleImprovedFoo(ImprovedFoo foo)
{
//do something involving ImprovedFoo
}
}
The thing that makes me cringe in the example above is the if-statements that appear in ImprovedFooHandler.handleFoo
Is there a way to avoid using the if-statements and the instanceof operator?
First of all the code you wrote won't work.
Each time you see instanceof and if...else together be very careful. The order of these checks is very important. In your case you'll never execute handleImpovedFoo. Guess why :)
It's absolutely normal you have these instanceof statements. Sometimes it's the only way to provide different behavior for a subtype.
But here you can use another trick: use simple Map. Map classes of foo-hierarchy to instances of fooHandler-hierarchy.
Map<Class<? extends Foo>, FooHandler> map ...
map.put( Foo.class, new FooHandler() );
map.put( ImprovedFoo.class, new ImprovedFooHandler() );
Foo foo ...; // here comes an unknown foo
map.get( foo.getClass() ).handleFoo( foo );
The best way of handling this depends too much on the individual case to provide a general solution. So I'm going to provide a number of examples and how I would solve them.
Case 1: Virtual File System
Clients of your code implement virtual file systems which enable them to operate any sort of resource which can be made to look like a file. They do so by implementing the following interface.
interface IFolder
{
IFolder subFolder(String Name);
void delete(String filename);
void removeFolder(); // must be empty
IFile openFile(String Name);
List<String> getFiles();
}
In the next version of your software you want to add the ability to remove a directory and all it contents. Call it removeTree. You cannot simply add removeTree to IFolder because that will break all users of IFolder. Instead:
interface IFolder2 implements IFolder
{
void removeTree();
}
Whenever a client registers an IFolder (rather then IFolder2), register
new IFolder2Adapter(folder)
Instead, and use IFolder2 throughout your application. Most of your code should not be concerned with the difference about what old versions of IFolder supported.
Case 2: Better Strings
You have a string class which supports various functionality.
class String
{
String substring(int start, end);
}
You decide to add string searching, in a new version and thus implement:
class SearchableString extends String
{
int find(String);
}
That's just silly, SearchableString should be merged into String.
Case 3: Shapes
You have a shape simulation, which lets you get the areas of shapes.
class Shape
{
double Area();
static List<Shape> allShapes; // forgive evil staticness
}
Now you introduce a new kind of Shape:
class DrawableShape extends Shape
{
void Draw(Painter paint);
}
We could add a default empty Draw method to Shape. But it seems incorrect to have Shape have a Draw method because shapes in general aren't intended to be drawn. The drawing really needs a list of DrawableShapes not the list of Shapes that is provided. In fact, it may be that DrawableShape shouldn't be a Shape at all.
Case 4: Parts
Suppose that we have a Car:
class Car
{
Motor getMotor();
Wheels getWheels();
}
void maintain(Car car)
{
car.getMotor().changeOil();
car.getWheels().rotate();
}
Of course, you know somewhere down the road, somebody will make a better car.
class BetterCar extends Car
{
Highbeams getHighBeams();
}
Here we can make use of the visitor pattern.
void maintain(Car car)
{
car.visit( new Maintainer() );
}
The car passes all of its component parts to calls into ICarVisitor interface allowing the Maintainer class to maintain each component.
Case 5: Game Objects
We have a game with a variety of objects which can be seen on screen
class GameObject
{
void Draw(Painter painter);
void Destroy();
void Move(Point point);
}
Some of our game objects need the ability to perform logic on a regular interval, so we create:
class LogicGameObject extends GameObject
{
void Logic();
}
How do we call Logic() on all of the LogicGameObjects? In this case, adding an empty Logic() method to GameObject seems like the best option. Its perfectly within the job description of a GameObject to expect it to be able to know what to do for a Logic update even if its nothing.
Conclusion
The best way of handling this situations depends on the individual situation. That's why I posed the question of why you didn't want to add the functionality to Foo. The best way of extending Foo depends on what exactly you are doing. What are you seeing with the instanceof/if showing up is a symptom that you haven't extended the object in the best way.
In situations like this I usually use a factory to get the appropriate FooHandler for the type of Foo that I have. In this case there would still be a set of ifs but they would be in the factory not the implementation of the handler.
Yes, don't violate LSP which is what you appear to be doing here. Have you considered the Strategy pattern?
This looks like a plain simple case for basic polymorphism.Give Foo a method named something like DontWorryI'llHandleThisMyself() (um, except without the apostrophe, and a more sensible name). The FooHandler just calls this method of whatever Foo it's given. Derived classes of Foo override this method as they please. The example in the question seems to have things inside-out.
With the visitor pattern you could do something like this,
abstract class absFoo {}
class Foo extends absFoo
{
protected int z;
}
class ImprovedFoo extends absFoo
{
protected double k;
}
interface FooHandler {
void accept(IFooVisitor visitor, absFoo foo);
}
class DefaultFooHandler implements FooHandler
{
public void accept(IFooVisitor visitor, absFoo foo)
{
visitor.visit(this, foo);
}
public void handleFoo(absFoo foo) {
System.out.println("DefaultFooHandler");
}
}
class ImprovedFooHandler implements FooHandler
{
public void handleFoo(absFoo foo)
{
System.out.println("ImprovedFooHandler");
}
public void accept(IFooVisitor visitor, absFoo foo) {
visitor.visit(this, foo);
}
}
interface IFooVisitor {
public void visit(DefaultFooHandler fooHandler, absFoo foo);
public void visit(ImprovedFooHandler fooHandler, absFoo foo);
}
class FooVisitor implements IFooVisitor{
public void visit(DefaultFooHandler fHandler, absFoo foo) {
fHandler.handleFoo(foo);
}
public void visit(ImprovedFooHandler iFhandler, absFoo foo) {
iFhandler.handleFoo(foo);
}
}
public class Visitor {
public static void main(String args[]) {
absFoo df = new Foo();
absFoo idf = new ImprovedFoo();
FooHandler handler = new ImprovedFooHandler();
IFooVisitor visitor = new FooVisitor();
handler.accept(visitor, idf);
}
}
But this does not guarantee only Foo can be passed to DefaultFooHandler. It allows ImprovedFoo also can be passed to DefaultFooHandler. To overcome, something similar can be done
class Foo
{
protected int z;
}
class ImprovedFoo
{
protected double k;
}
interface FooHandler {
void accept(IFooVisitor visitor);
}
class DefaultFooHandler implements FooHandler
{
private Foo iFoo;
public DefaultFooHandler(Foo foo) {
this.iFoo = foo;
}
public void accept(IFooVisitor visitor)
{
visitor.visit(this);
}
public void handleFoo() {
System.out.println("DefaultFooHandler");
}
}
class ImprovedFooHandler implements FooHandler
{
private ImprovedFoo iFoo;
public ImprovedFooHandler(ImprovedFoo iFoo) {
this.iFoo = iFoo;
}
public void handleFoo()
{
System.out.println("ImprovedFooHandler");
}
public void accept(IFooVisitor visitor) {
visitor.visit(this);
}
}
interface IFooVisitor {
public void visit(DefaultFooHandler fooHandler);
public void visit(ImprovedFooHandler fooHandler);
}
class FooVisitor implements IFooVisitor{
public void visit(DefaultFooHandler fHandler) {
fHandler.handleFoo();
}
public void visit(ImprovedFooHandler iFhandler) {
iFhandler.handleFoo();
}
}
public class Visitor {
public static void main(String args[]) {
FooHandler handler = new DefaultFooHandler(new Foo());
FooHandler handler2 = new ImprovedFooHandler(new ImprovedFoo());
IFooVisitor visitor = new FooVisitor();
handler.accept(visitor);
handler2.accept(visitor);
}
}