Constructor or factory method?
Hi!
This is probebly a wery simple problem but i havn't found a good answer.
I have a class that read/write to a specified file on disk. If an object hasn't existed before i want to pas a filename to create the object. When the object has already existed and already has an file on disk i also whant to get an instance of the object by passing in a file.
Both cases the constructor taks the same argument but i realy need tow seperate constructors. What should i do? Is there any pattern on this issue? Maby one of the constructors should be a factory method?
Thanks!
/Christer
If I am understanding you question correctly, you definitely want a factory. Don't have any public constructors. Here's an example that you can adapt as needed.
public final class FileFactory
private static final Map files = new HashMap();
private FileFactory(){}
public static File getFile(String name)
File file = files.get(name);
if (file == null)
file = new File(name);
files.put(name, file);
return file;
}If you want to sometimes return an existing instance, a constructor cannot possibly work for you. Constructors only return new instances.
Similar Messages
-
Static factory methods, instead of constructor
Hi All,
why we use static factory methods, instead of constructor.
Apart from Singleton class , what is use of static factory methods ?
Thanks in Advance,
RishiOne reason for using factories is that they simplify creating instances of immutable classes that might otherwise have messy constructors with lots of arguments.
-
Problem in factory method, how to pass arguments ?
Hello it's me again :)
here's the code :
package print;
import java.util.*;
import static print.Print.*;
interface Fact<T> {
T create(String n);;
T create ();
class PetColl {
public String toString() {
return getClass().getSimpleName();
static List<Fact<? extends Pet>> petSpecies=
new ArrayList<Fact<? extends Pet>>();
static {
// Collections.addAll() gives an "unchecked generic
// array creation ... for varargs parameter" warning.
petSpecies.add(new Cymric.Factory());
petSpecies.add(new EgyptianMau.Factory());
petSpecies.add(new Hamster.Factory());
petSpecies.add(new Manx.Factory());
petSpecies.add(new Mouse.Factory());
petSpecies.add(new Pug.Factory());
petSpecies.add(new Mutt.Factory());
petSpecies.add(new Rat.Factory());
private static Random rand = new Random(47);
public static Pet createRandom() {
int n = rand.nextInt(petSpecies.size());
return petSpecies.get(n).create();
public Pet[] createArray(int size) {
Pet[] result = new Pet[size];
for(int i = 0; i < size; i++)
result[i] = createRandom();
return result;
public ArrayList<Pet> arrayList(int size) {
ArrayList<Pet> result = new ArrayList<Pet>();
Collections.addAll(result, createArray(size));
return result;
class Individual implements Comparable<Individual> {
private static long counter = 0;
private final long id = counter++;
private String name;
public Individual(String name) { this.name = name; }
// ?name? is optional:
public Individual() {}
public String toString() {
return getClass().getSimpleName() +
(name == null ? "" : " " + name);
public long id() { return id; }
public boolean equals(Object o) {
return o instanceof Individual &&
id == ((Individual)o).id;
public int hashCode() {
int result = 17;
if(name != null)
result = 37 * result + name.hashCode();
result = 37 * result + (int)id;
return result;
public int compareTo(Individual arg) {
// Compare by class name first:
String first = getClass().getSimpleName();
String argFirst = arg.getClass().getSimpleName();
int firstCompare = first.compareTo(argFirst);
if(firstCompare != 0)
return firstCompare;
//second compare by name
if(name != null && arg.name != null) {
int secondCompare = name.compareTo(arg.name);
if(secondCompare != 0)
return secondCompare;
}//third compare by id
return (arg.id < id ? -1 : (arg.id == id ? 0 : 1));
class Pets {
public static final PetColl creator =
//new LiteralPetCreator();
new PetColl();
public static Pet randomPet() {
return creator.createRandom();
public static Pet[] createArray(int size) {
return creator.createArray(size);
public static ArrayList<Pet> arrayList(int size) {
return creator.arrayList(size);
class Person extends Individual {
String name;
public static class Factory implements Fact<Person>{
public Person create(String name){
Person.name=name;
return new Person(); }
public Person create(){return new Person();}
class Pet extends Individual {
class Dog extends Pet {
class Mutt extends Dog {
public static class Factory implements Fact<Mutt> {
public Mutt create(String name){return new Mutt(name);}
public Mutt create () {return new Mutt();}
class Pug extends Dog {
public static class Factory implements Fact<Pug> {
public Pug create(String name){return new Pug(name);}
public Pug create () {return new Pug();}
class Cat extends Pet {
class EgyptianMau extends Cat {
public static class Factory implements Fact<EgyptianMau> {
public EgyptianMau create(String name){return new EgyptianMau(name);}
public EgyptianMau create () {return new EgyptianMau();}
class Manx extends Cat {
public static class Factory implements Fact<Manx> {
public Manx create(String name){return new Manx(name);}
public Manx create () {return new Manx();}
class Cymric extends Manx {
public static class Factory implements Fact<Cymric> {
public Cymric create(String name){return new Cymric(name);}
public Cymric create () {return new Cymric();}
class Rodent extends Pet {
class Rat extends Rodent {
public static class Factory implements Fact<Rat> {
public Rat create(String name){return new Rat(name);}
public Rat create () {return new Rat();}
class Mouse extends Rodent {
public static class Factory implements Fact<Mouse> {
public Mouse create(String name){return new Mouse(name);}
public Mouse create () {return new Mouse();}
class Hamster extends Rodent {
public static class Factory implements Fact<Hamster> {
public Hamster create(String name){return new Hamster(name);}
public Hamster create () {return new Hamster();}
public class Test {
public static void main(String[] args) {
for(Pet p:Pets.creator.arrayList(25)){
PetCount.petC.count(p.getClass().getSimpleName());
print(p.getClass().getSimpleName());}
class PetCount {
static class PetCounter extends HashMap<String,Integer> {
public void count(String type) {
Integer quantity = get(type);
if(quantity == null)
put(type, 1);
else
put(type, quantity + 1);
public static PetCounter petC= new PetCounter();
}and here's my problem:
I'm trying to fill up list using factory method but in a fact that I want to have two constructors, I have a problem to set field name of objects of those classes. Is there any possibility to use in that way some factory method to create that list ?
In Person class I've tried to set it in factory method before creating an object, but as you know that option is only alvailable for static fields which i don't want to be static.I for one have no idea what you're asking, and what you seem to be saying doesn't make sense.
I'm trying to fill up list using factory method but in a fact that I want to have two constructors,Two constructors for what? The factory class? The classes that the factory instantiates?
I have a problem
to set field name of objects of those classes. Is there any possibility to use in that way some factory method to
create that list ?What?
In Person class I've tried to set it in factory method before creating an object, but as you know that option is only alvailable for static fields which i don't want to be static.That doesn't make any sense. A Factory can easily set fields in the objects it creates on the fly (not static). -
Hey all, I am tying to learn factory method and working on an example from the Oreilly AS3 Design patterns book. I am attempting figure out how all the classes work together in this design pattern and I have a question I am hoping someone might be able clearify for me.
In the document class "Main" I have the following code in the constructor
// instantiate concrete shape creators
var unfilledShapeCreator:ShapeCreator = new UnfilledShapeCreator( );
// draw unfilled shapes NOTE: draw() is a method of the ShapeCreator class
unfilledShapeCreator.draw(UnfilledShapeCreator.CIRCLE, this.stage, 50, 75);
I get what is going on there, so I open up the 'UnfilledShapeCreator" class and it has the following:
package shapecreators
/* Concrete Creator class */
public class UnfilledShapeCreator extends ShapeCreator
public static const CIRCLE :uint = 0;
public static const SQUARE :uint = 1;
//implement the createShape factory method from the ShapeCreator Class.
override protected function createShape(cType:uint):ShapeWidget
if (cType == CIRCLE)
trace("Creating new circle shape");
return new CircleWidget( ); //Instantiates circleWidge Product Class
} else if (cType == SQUARE) {
trace("Creating new square shape");
return new SquareWidget( ); //Instantiates square Widge Product Class
} else {
throw new Error("Invalid kind of shape specified");
return null;
and the ShapeCreator class is as follows
package shapecreators
/* Defines the abstract interface for the creator classes */
import flash.display.DisplayObjectContainer;
import flash.errors.IllegalOperationError;
// ABSTRACT Class (should be subclassed and not instantiated)
public class ShapeCreator
public function draw(cType:uint, target:DisplayObjectContainer, xLoc:int, yLoc:int):void
var shape = this.createShape(cType);
shape.drawWidget( );
shape.setLoc(xLoc, yLoc); // set the x and y location
target.addChild(shape); // add the sprite to the display list
// ABSTRACT Method (must be overridden in a subclass)
protected function createShape(cType:uint):ShapeWidget
throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
return null;
My question is: how does the cType parameter get passed into the createShape method? This method does not seem to get called from anywhere or any other class. I see how FilledShapeCreator.CIRCLE gets passed to the draw method in the ShapeCreator class, but the createShape method is never called like the draw method is.
Is it because createShape is called within the draw function?
I am quite sure it is a simple answer, but it has me completely lost.
Thanks,Yes, it is called by super class in line:
var shape = this.createShape(cType);
By the way, I don't know where you got code but it is a pretty bad practice not type variables. Good compiler should not even allow you to compile. The line above should be:
var shape:ShapeWidget = this.createShape(cType); -
What is a Factory method and when to use this concept?
Could any one please describe what a factory method is and explain how I can use it by giving a simple example
A Factory Method (sometimes called a "virtual constructor") is a way to avoid hard coding what class is instantiated. Consider:
DataSource myDataSource = new DataSource();Now, if you want to use some other DataSource in your app, say, an XMLDataSource, then you get to change this code and all subsequent lines that use this, which can be a lot. If, however, you specified and interface for your DataSources, say, IDataSource, and you gave the DataSource class a static "create" method that would take some indication of what sort of DataSource to actually use, then you could write code like:
IDataSource myDataSource = DataSource.create(dataSourceString);And be able to pass in a dataSourceString describing what DataSource you wanted to use - and not have to recompile. Check out the Java Design Patterns site ( http://www.patterndepot.com/put/8/JavaPatterns.htm )
Make sense?
Lee -
can anybody guide me on what static factory methods are, how they are invoked and there advantages over constructors.
Joshua Bloch has a good bit on it in his book Effective Java. If you don't have that then I suggest Google as it's been explained to death before. Static factory methods are for all intents and purposes when you provide a static method that returns an instance of a given object rather than having a public constructor.
-
How to use singloeton factory methods ?
Hi Guys,
Can any one please help me like how to use singleton factory methods in oops? i am very new to OOPS concepts ?
Thanks in advancePRINTER - part2
METHOD constructor.
"initial printer cartridge fill
me->number = i_number.
me->cartridge = i_units.
me->cost = me->cartridge * 10.
ENDMETHOD.
METHOD increase_cost.
cost = cost + i_units.
ENDMETHOD.
METHOD consume_cartrigde.
cartridge = cartridge - i_units.
ENDMETHOD.
METHOD get_total_cost.
DATA lo_printer TYPE REF TO lcl_printer.
LOOP AT it_printers INTO lo_printer.
r_cost = r_cost + lo_printer->get_cost( ).
ENDLOOP.
ENDMETHOD.
METHOD get_cost.
r_cost = cost.
ENDMETHOD.
METHOD get_cartridge.
r_cartridge = cartridge.
ENDMETHOD.
METHOD get_number.
r_number = number.
ENDMETHOD.
* helper method to show current state of printers
METHOD show_printers.
DATA lv_mess TYPE string.
DATA lv_number TYPE i.
DATA lv_cartridge TYPE i.
DATA lv_cartridge_c TYPE c LENGTH 5.
DATA lv_cost TYPE i.
DATA lv_cost_c TYPE c LENGTH 5.
DATA lv_number_c TYPE c LENGTH 2.
DATA lo_printer TYPE REF TO lcl_printer.
LOOP AT it_printers INTO lo_printer.
lv_number_c = lv_number = lo_printer->get_number( ).
lv_cost_c = lv_cost = lo_printer->get_cost( ).
lv_cartridge_c = lv_cartridge = lo_printer->get_cartridge( ).
CONCATENATE lv_mess 'Printer:' lv_number_c ', cost:' lv_cost_c ', cartridge:' lv_cartridge_c
cl_abap_char_utilities=>cr_lf INTO lv_mess SEPARATED BY space.
ENDLOOP.
MESSAGE lv_mess TYPE 'I'.
ENDMETHOD.
ENDCLASS.
CLIENT
DATA go_printer TYPE REF TO lcl_printer. "printers
DATA go_job TYPE REF TO lcl_job. "job
DATA gv_mess TYPE string.
DATA: gv_number TYPE i,
gv_number_c TYPE c LENGTH 10.
SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME.
PARAMETERS: pa_print TYPE i OBLIGATORY, "printer number
pa_units TYPE i DEFAULT 100. "initial printer filling
SELECTION-SCREEN PUSHBUTTON /10(15) addp USER-COMMAND fcadd VISIBLE LENGTH 15.
SELECTION-SCREEN PUSHBUTTON /10(15) refil USER-COMMAND fcref VISIBLE LENGTH 15.
SELECTION-SCREEN PUSHBUTTON /10(15) show USER-COMMAND fcshow VISIBLE LENGTH 15.
SELECTION-SCREEN PUSHBUTTON /10(15) print USER-COMMAND fcprnt VISIBLE LENGTH 15.
SELECTION-SCREEN PUSHBUTTON /10(15) total USER-COMMAND fctot VISIBLE LENGTH 15.
SELECTION-SCREEN END OF BLOCK bl1.
SELECTION-SCREEN BEGIN OF BLOCK bl2 WITH FRAME.
PARAMETERS: pa_col TYPE c1,
pa_pages TYPE i,
pa_numb TYPE i. "to which printer you want the job be send to
SELECTION-SCREEN END OF BLOCK bl2.
INITIALIZATION.
addp = 'Add printer'.
show = 'Show printers'.
print = 'Print'.
total = 'Total cost'.
refil = 'Refill'.
AT SELECTION-SCREEN.
CLEAR: gv_number, gv_number_c, gv_mess.
CASE sy-ucomm.
WHEN 'FCADD'.
go_printer = lcl_printer=>factory( i_number = pa_print
i_units = pa_units ).
WHEN 'FCSHOW'.
IF go_printer IS NOT BOUND.
MESSAGE 'Add at least one printer first' TYPE 'E'.
ELSE.
go_printer->show_printers( ).
ENDIF.
WHEN 'FCPRNT'.
IF pa_pages IS INITIAL.
MESSAGE 'Provide number of pages' TYPE 'E'.
ENDIF.
CREATE OBJECT go_job EXPORTING i_pages = pa_pages i_color = pa_col.
IF lcl_printer=>get_printer( pa_numb ) IS NOT BOUND.
gv_number_c = pa_numb.
condense gv_number_c.
CONCATENATE 'Printer' gv_number_c 'doesn`t exist, select correct one' INTO gv_mess SEPARATED BY space.
MESSAGE gv_mess TYPE 'E'.
ELSE.
go_printer->print( i_number = pa_numb
io_job = go_job ).
ENDIF.
WHEN 'FCTOT'.
IF go_printer IS BOUND.
gv_number_c = gv_number = go_printer->get_total_cost( ).
ENDIF.
CONCATENATE 'Total cost of all printers for printing and initial cartridge filling is: ' gv_number_c INTO gv_mess
SEPARATED BY space.
MESSAGE gv_mess TYPE 'I'.
WHEN 'FCREF'.
IF lcl_printer=>get_printer( pa_print ) IS NOT BOUND.
gv_number_c = pa_print.
CONCATENATE 'Printer doesn`t exist' gv_number_c INTO gv_mess SEPARATED BY space.
MESSAGE gv_mess TYPE 'E'.
ELSE.
go_printer->fill_cartridge( i_number = pa_print
i_units = pa_units ).
ENDIF.
ENDCASE.
Regards
Marcin -
Singleton - Why have a factory method?
Question:
Why bother to have a factory method [represented by getServiceFacade() below] for a singleton? Accessing any of the static methods in the singleton causes class instantiation.
In other words, what advantage is there to invoking a method with ServiceFacade.getServiceFacade().method() vs. ServiceFacade.method() ???
public final class ServiceFacade
private static ServiceFacade serviceFacade = new ServiceFacade();
// Constructor for the ServiceFacade
private ServiceFacade()
Log.info("ServiceFacade.ServiceFacade(): enter");
try
initializeServices();
catch (Exception e)
Log.error("ServiceFacade.ServiceFacade() Exception: static class not initialized.");
Log.info("ServiceFacade.ServiceFacade(): exit");
//public static ServiceFacade getServiceFacade()
// Log.info("ServiceFacade.getServiceFacade(): enter/exit");
// return serviceFacade;
private static synchronized void initializeServices()
throws ValidationException, MarshalException, IOException
// A bunch of stuff here ...The idea behind a Singleton is that it allows some in-memory caching of state, since once a Singleton is instantiated, it stays in memory (being self-referential) as long as the JVM runs. Generally, the only static method is the "getInstance" (or in your case "getServiceFacade").
During the initialization, the Singleton factory will typically perform a lot of "expensive" operations (e.g. JNDI lookups, establishing connection pools, etc.) and then hold on to this information, so that it doesn't have to do it again, making all subsequent operations that much faster. -
Could someone explain the Factory Method Design Pattern
Hi Experts.
Could someone please explain for me the Factory Method Design Pattern. I read it a little and I understand that it is used in JDBC drivers but i'm not clear on it.
Could someone explain.
Thanks in advance
stephenBasically, you have one class that's sole purpose is to create instances of a set of other classes.
What will usually happen is you have a set of related classes that inherit from some base class. We'll say for example that you have a base class CAR and it has sub-classes FORD, GM, HONDA (sorry Crylser). Instead of having the user call the constructors for FORD, GM, and HONDA, you can give the user a Factory Class that will give him a copy. We'll call our factory class Dealership. Inside dealership, you can have a static function :
public static Car makeCar(String type)
if(type.equals("FORD")
return new FORD();
else if(type.equals("GM")
return new GM();
else if(type.equals("HONDA")
return new HONDA();
So when the user needs a car, they will just call
Dealership.makeCar("FORD").
This is a good way to hide the implementation of your classes from the user, or if you require complex initialization of your objects.
Another good example of this is in the Swing library. To get a border around a component, you call static methods on BorderFactory.
Hope this helped.
Ed -
Factory, Factory Method etc.. - method name conventions?
hi,
this might be a minor point but is there a convention for naming methods whose job is a level of indirection for obtaining new objects? in the java libraries there are methods that do this with various names eg.
newMyObject()
createMyObject()
and i think i've seen
getMyObject() somewhere (not as a normal getter but as an object creator) but will check..
thanks,
asjfBased on code I have seen, both in real work and on the Web, I'd say that there are only organization-wide , if not personal, conventions - no universal naming scheme - so you'll probably get only personal feelings.
As for a general convention, I have seen all forms you propose, so none of it is either a defacto standard, nor universally rejected...
As for my personal (but argumented) feelings:
I favor getMyObject(), as it's rarely misleading, especially if it's already in a Factory class. This way, a factory method implementation will have the freedom to create a new object or reuse an existing one.
Actually it's not very different from getters, whose point is to return a "property" value, no matter whether this value is calculated or stored.
The createMyObject() flavor is a bit too explicit to allow for reusing of cached or recycled objects, but it is the clearest form for a factory method that would by design be required to always return a newly created object.
The newMyObject() form has the same overspecifying drawback, plus the additional flaw of being easy to misread - and actually understood as a constructor invocation. So I avoid it - and frown when I see it.
I sometimes use getOrCreateMyObject(), though not exactly as a factory method, rather for getters of a property I don't want to be null (and which has a reasonable default value, of course).
I must admit, this hasn't got a huge enthusiasm from my colleagues either... -
LOGO required in ALV top of page using factory method
Hi,
I am doing an ALV using factory method of class Cl_SALV_TABLE. Can any one help me about putting a LOGO on the top of page.
Thanks in advance.
AmitavaHi,
In START-OF-SELECTION.
put form to display header
like PERFORM build_header
gr_table->display( ).
then...
in FORM
FORM build_header.
lr_grid TYPE REF TO cl_salv_form_layout_grid,
lr_logo TYPE REF TO cl_salv_form_layout_logo,
create object lr_logo.
lr_logo->set_left_content( lr_grid ).
lr_logo->set_right_logo( 'LOGO_NAME' ).
* Set the element top_of_list
gr_table->set_top_of_list( lr_logo ).
ENDFORM.
thanx. -
How to add a new button in an ALV using factory method
im using factory method to creat an ALV
The reason why I'm doing this is because I want the ALV and the selection screen in the same screen like exemplified here http://help-abap.blogspot.com/2008/10/dispaly-alv-report-output-in-same.html
CALL METHOD cl_salv_table=>factory
EXPORTING
list_display = if_salv_c_bool_sap=>false
r_container = lo_cont
container_name = 'DOCK_CONT'
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = me->t_data.
The above code already uses every parameter that method as to offer.
Is it possible to add extra buttons to an ALV using that method?Hi Ann,
The reason you are not able to see any of the new columns as a option to select in your web service block is because when you have published that block, they were not present. Add these two new objects in your block and publish it again. You will be prompted for duplication content. Select the highlighted block for duplicate and now you can see the new added objects in the filter option. Update and this will overwrite your published block. Please note, web services do appear to behave weirdly when used with dashboards so I request you to please try it in a separate test report first.
Hope that helps.
Regards,
Tanisha -
Meaning of factory method in abap objects
Hi,
Can anybody help me in understanding the meaning of factory method in abap object? what is the importance of this?
Regards
SudhansuHi Krish and Sudhansu,
Design patterns are solutions which are already verified and known by many developers. That is why it is worth to use them. There is no need to reinvent the wheel in many cases.
I would recommend book which is placed in the ABAP world:
http://www.sap-press.com/products/Design-Patterns-in-Object%252dOriented-ABAP-(2nd-Edition).html
Although Java language has intuitive syntax, there are some special things in ABAP development so it is better to check solutions adjusted for ABAP editor.
The most common usage of factory pattern is to simplify object creation.
- By one method call you provide required parameters and do all initializations, including dependent objects.
- Class can have many factory methods, if you want to provide more ways of initialization.
- Factory method is usually static in the class and they return initialized instance of object for this class.
- There is naming convention to start factory method name with "create" - easy to recognize pattern.
- If you set property of class to "private instantiation" then you force to use factory method for object creation. In this way it is really simple to find all places where object are created with given set of input parameters - find references of factory method.
Factory pattern becomes even more powerful if we add inheritance. Factory method returns basic object (like ZCL_VEHICLE) but its implementation can return different subclass instance, depending on input parameter (ZCL_CAR, ZCL_TRAIN etc). Each instance can implement differently behavior (methods implementation), but these are object oriented techniques.
Regards,
Adam -
Parent constructor calls abstract method
Hi everybody!
I'm wondering if there is something wrong with java or if the idea is just too ill?
Anyway, I think it would be great if this hierachy would work...
Two classes A and B.
Class A defines an astract method.
In A's constructor this abstract method is called.
Class B extends A and provides an implementation for the abstract method in A.
Class B also defines a member variable that is set in B's implementation of the abstract method.
In class' B constructor the parent constructor A() is called.
example:
public abstract class A {
public A() {
createComponents();
public abstract void createComponents();
public class B extends A {
private String string = null;
public B() {
super();
System.out.println("B::B() " + string);
public void createComponents() {
System.out.println("B::createComponents() begin");
string = new String("test");
System.out.println("B::createComponents() " + string);
public void describe() {
System.out.println("B::describe() " + string);
public static void main(String[] args) {
B b = new B();
b.describe();
}running the code above produces the following output:
B::createComponents() begin
B::createComponents() test
B::B() null
B::describe() null
why is the string member variable null in B's constructor??
thanks in advance
Peter Bachl
Polytechnic University of Upper Austria, Hagenberg
[email protected]The answer is that the call of the super-constructor
is allways done before the initialization
of the member variable. That's all and that's the
normal behavior.
order :
- initialization of static variables
- call to the super-constructor
- initialization of the instance variables
- execution of the constructor
Since this is the advanced forum it is relevant to point out that that is not exactly true.
There is a step in java that 'initializes' member variables before any constructors are called, super or other wise.
From the JLS 12.5...
Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (4.5.5)
Using the following code as an example
class MyClass
int i1;
int i2 = 1;
.When creating an instance of the above there will be three 'initializations'
// Part of object creation...
i1 = 0; // The default value
i2 = 0; // The default value
// Part of construction...after super ctors called.
i2 = 1; // The variable initializer (see step 4 of JLS 12.5)
Unfortunately the descriptions are rather similar and so confusion can result as to when the assignment actually occurs. -
Trying to understand Objective C warning related to factory method
All,
I'm just beginning learning objective C (I am a C++ programmer by day), and I have a question about a warning I am seeing in my code. I found some really simple example code on the web that used the 'new' factory method to create an instance of an object. Here are the three files:
List.h
#import <objc/Object.h>
@interface List : Object // List is a subclass of the superclass Object
int list[100]; // These are instance variables.
int size;
/* Public methods */
- free;
- (int) addEntry: (int) num;
- print;
/* Private methods */
/* Other programs should not use these methods. */
- resetSize;
@end
List.m
#import "List.h"
@implementation List
+ new // factory method
self = [super new];
printf("inside new\n");
[self resetSize];
return self;
- free
return [super free];
- (int) addEntry: (int) num
list[size++] = num;
return size;
- print
int i;
printf("\n");
for (i = 0; i < size; ++i)
printf ("%i ", list);
return self; // Always return self
// if nothing else makes sense.
- resetSize
printf("Inside resetSize\n");
size = 0;
return self;
@end
main.m
#import <objc/Object.h>
#import "List.h" // Note the new commenting style.
main()
id list; // id is a new data type for objects.
list = [List new]; // create an instance of class List.
[list resetSize];
[list addEntry: 5]; // send a message to the object list
[list print];
[list addEntry: 6];
[list addEntry: 3];
[list print];
printf("\n");
[list free]; // get rid of object
Now, I know that the 'best' way to allocate and initialize an object is through [[List alloc] init], but I'm seeing a strange warning when I compile List.m, and I just want to understand why it's showing up. Here's the warning.
List.m: In function ‘+[List new]’:
List.m:9: warning: ‘List’ may not respond to ‘+resetSize’
List.m:9: warning: (Messages without a matching method signature
List.m:9: warning: will be assumed to return ‘id’ and accept
List.m:9: warning: ‘...’ as arguments.)
It looks like something is assuming that resetSize is a factory method rather than an instance method. The strange thing, though, is that the program works exactly like expected. resetSize is actually called from within the new method correctly.
Any ideas why I'm seeing the error, and how I should get rid of it?
Thanks,
EricThanks for clearing that up for me - it makes sense now. And sorry about the formatting problems - I guess forgetting the {code} tags make a pretty big difference
It's taking a little bit for my mind to switch from C++ syntax to Objective C, but I'm able to visualize the problem and the reason the code I found produced the error.
Thanks again,
Eric
Maybe you are looking for
-
Showmount: HOSTNAME: RPC: Program not registered
I am new to solaris. I have solaris 10 installed in one of my machines. When i try to list the remote mounts using the command "showmount", i am getting the error "RPC:Program not registered" . I am not aware of which services i have to check/start t
-
Keypad and home answer machine
I like to call my house from my phone to see if I have any messages. I dial my number with the phone and when my machine answers I need to key in numbers 1,2,3 to get my messages. How can I get back to the number pad to type the 1,2,3 from the screen
-
Does solaris dhcp server support user class
Does solaris dhcp server support user class(option 77). In my environment, solaris dhcp server seems just ignore this option set in the client dhcp discover. Does anybody can help me.
-
No ascending calendar alarm tone in N82
I'm having some problems with the sound level of the calendar alarm in my new Nokia N82. I have the ringing type set to ascending in the phone profile and both the alarm clock and ringing volume start at a low level and increases which is what I want
-
I had no problems with making phone deposits on my Galaxy Stratosphere or on my husband's Galaxy S4. However, after at least 20 tries on my new Galaxy S5, I kept getting error messages from the bank app indicating that it couldn't read it, to make s