Trabajar con clases (heredar), @ Propiedades e inicialización -- lasses campo con objective-c campo con inheritance camp codereview Relacionados El problema

Working with Classes (inheriting), @ properties and Initialization


3
vote

problema

Español

Estoy trabajando en esta asignación de programación del objetivo C que encontré en línea. No estoy seguro de si he cumplido con todos los requisitos, especialmente la Parte C. Cualquier ayuda o sugerencia será apreciada.

parte 6

a) Implementar la clase A CON PROPIEDADES a1 , a22 y a33 ( a34 < / Código>, string , int ).

b) Los nuevos objetos se inicializan automáticamente a 1 , 9988776655544338 , a39 .

c) también proporciona inicializador a cualquier dato y constructor (llamado sin ningún problema) hacer lo mismo.

d) Asegúrese de a10 OB Objeto de a11 imprimirá todos los datos.

E) Luego implementar a12 HERRITAR DESDE a13 . a14 Agrega la propiedad a15 a16 .

f) Asegúrese de que a17 funciona como a18 , que es un objeto nuevo se inicializa en a19 , 99887766555443320 , a21 , y a22 (los nuevos datos). El resto también debe trabajar en a23 .

  a24  
Original en ingles

I'm working on this Objective C programming assignment I found online. I'm not sure if I have met all the requirements, especially part C. Any help or suggestion will be appreciated.

Part 6

a) Implement class A with properties a1, a2, and a3 (int, string, int).

b) New objects are automatically initialized to 1, "hello", 1.

c) Also provide initializer to any data and constructor (called without alloc) to do the same.

d) Make sure %@ ob object of A will print all data.

e) Then implement B inheriting from A. B adds property b (string).

f) Make sure B works as A, that is new object is initialized to 1, "hello", 1, and 3 (the new data). The rest also must work on B.

   //classA.h file #import <Foundation/Foundation.h>  @interface ClassA : NSObject // Part 6a @property int a1; @property NSString *a2; @property int a3;  -(NSString *) description; -(id) initWithA1: (int) x andA2: (NSString *) s andA3: (int) y; -(id) init; @end   //classA.m file #import "ClassA.h"  @implementation ClassA    -(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y {     self = [super init];     if (self) {         self.a1 = x;         self.a2 = s;         self.a3 = y;     }     return self; }  // part 6b - (id) init {     return [self initWithA1:1 andA2:@"hello" andA3:1]; }  // part 6d -(NSString *) description {     return [NSString stringWithFormat:@"ClassA a1 = %d , a2 = %@ , a3 = %d", self.a1, self.a2, self.a3]; }  @end   //classB.h file #import "ClassA.h"  @interface ClassB : ClassA @property int a1; @property NSString *a2; @property int a3; @property NSString * b;  -(NSString *) description; -(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB: (NSString *) z; -(id) init; @end   //classB.m file #import "ClassB.h"  @implementation ClassB  -(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB:(NSString *)z {     self = [super init];     if (self) {         self.a1 = x;         self.a2 = s;         self.a3 = y;         self.b = z;     }     return self; }  -(id) init {     return [self initWithA1:1 andA2:@"hello" andA3:1 andB:@"3"]; }  -(NSString *) description {     return [NSString stringWithFormat:@"ClassB a1 = %d , a2 = %@ , a3 = %d , b = %@" , self.a1, self.a2, self.a3, self.b]; }  @end    //viewController.m file #import "ViewController.h" #import "ClassA.h" #import "ClassB.h" @interface ViewController ()  @end  @implementation ViewController  - (void)viewDidLoad {     [super viewDidLoad];     ClassA * a = [ClassA new];     NSLog(@"%@", a);      ClassB * j = [ClassB new];     NSLog (@"%@", j); }  - (void)didReceiveMemoryWarning {     [super didReceiveMemoryWarning];     // Dispose of any resources that can be recreated. }  @end 
        
 
 

Lista de respuestas

4
 
vote
vote
La mejor respuesta
 

Este código hace lo que se le pide que haga. Pero todavía puede ser mejor.

En primer lugar, en init y los métodos de fábrica, es bueno usar instancetype como el tipo de retorno en lugar de id . instancetype Le permite volver a devolver el tipo correcto cuando ha subclasificado, pero no devuelve el 998877766655544334 que se puede asignar a cualquier cosa. Queremos asegurarnos de que el IDE pueda vernos algunos, y 9988776655544335 lo ayudará a hacerlo.


Segundo, no deberíamos estar usando and en los nombres de los métodos como este. La palabra and En los nombres de los métodos se utiliza para indicar acciones distintas. Solo hay una sola acción que se está llevando a cabo aquí, por lo que nuestro nombre de método debe parecer más de esto:

  -(id) initWithA1:(int)x A2:(NSString *)s A3:(int)y B: (NSString *) z;   

Además, los nombres de los parámetros deben coincidir. Realmente debería ser:

  - (instancetype)initWithA1:(int)a1 A2:(NSString *)a2 A3:(int)a3 B: (NSString *)b;   

Aunque realmente, los nombres de las variables deben ser aún mejores, pero esto es lo que requiere la asignación, así que lo dejaré deslizarse.


Los únicos otros problemas que veo es que la clase B no actúa como una subclase de un en absoluto. Deberíamos usar nuestra herencia.

  instancetype0  

Hay más disponibles para nosotros entonces simplemente instancetype1 . ¿Qué tal si prueba esto:

  instancetype2  

Vamos a permitir el método 99887766555443313 Cuidar los parámetros que cuida y sede B simplemente maneje los parámetros que B agrega.

ahora en B 'Código> instancetype4 MÉTODO:

  instancetype5  

de nuevo, no hacemos uso en todo el hecho de que somos una subclase.

En primer lugar, hagamos un pequeño cambio en el método 99887766555443316 , así:

  instancetype7  

Ahora en lugar de asumir este método ha sido convocado por instancetype8 , simplemente devolvemos el nombre de la clase como la primera parte de la cadena. Ahora vamos a mejorar B:

  instancetype9  

y Finalmente, podemos eliminar las declaraciones de propiedad de id0 , id1 , y id2 de id3 ' s id4 . Fueron declarados en A, que automáticamente los convierten en parte de todas las subclases de A.

 

This code does what it is asked to do. But it can still be better.

First of all, in init and factory methods, it is good to use instancetype as the return type rather than id. instancetype allows you to still return the correct type when you've subclassed, but it doesn't return the generic id that can be assigned to anything. We want to make sure the IDE can check us some, and instancetype will help it do that.


Second, we shouldn't be using and in method names like this. The word and in method names is used to indicate distinct actions happening. There's only a single action taking place here, so our method name should look more like this:

-(id) initWithA1:(int)x A2:(NSString *)s A3:(int)y B: (NSString *) z; 

Further more, the parameters names should match. It should really be:

- (instancetype)initWithA1:(int)a1 A2:(NSString *)a2 A3:(int)a3 B: (NSString *)b; 

Though truly, the variable names should be even better, but this is what the assignment requires, so I'll let it slide.


The only other problems I see is that class B doesn't act like a subclass of A at all. We should use our inheritance.

-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB:(NSString *)z {     self = [super init];     if (self) {         self.a1 = x;         self.a2 = s;         self.a3 = y;         self.b = z;     }     return self; } 

There's more available to us then simply [super init];. How about try this:

-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB:(NSString *)z {     self = [super initWithA1:x andA2:s andA3:y];     if (self) {         _b = z;     }     return self; } 

Let's let A's initWith... method take care of the parameters it takes care of and let B just handle the parameters that B adds.

Now in B's description method:

-(NSString *) description {     return [NSString stringWithFormat:@"ClassB a1 = %d , a2 = %@ , a3 = %d , b = %@" , self.a1, self.a2, self.a3, self.b]; } 

Again, we don't make use at all of the fact that we're a subclass.

First of, let's make a small change to A's description method, like so:

-(NSString *) description {     return [NSString stringWithFormat:@"%@ a1 = %d , a2 = %@ , a3 = %d",         [self class], self.a1, self.a2, self.a3]; } 

Now rather than assuming this method has been called for ClassA, we just return the name of the class as the first part of the string. Now let's improve B:

- (NSString *)description {     return [[super description] stringByAppendingFormat:@", b = %@", self.b]; } 

And finally, we can remove the property declarations of a1, a2, and a3 from b's @interface. They were declared in A, that automatically makes them a part of all of A's subclasses.

 
 
 
 
5
 
vote

Esta es mi primera revisión, así que tenga en cuenta cuando lo esté leyendo.

Lo primero que veo es que en la inicialización, no debe usar los colonos y los getters automáticos para las propiedades. La razón de esto es que el objeto no puede estar completamente inicializado, y por lo tanto puede fallar. Así que en lugar de hacer:

  id5  

Acceda a las propiedades directamente así:

  id6  

De lo contrario, su patrón de inicio es bueno, y los puntos de bonificación por tener un inicio predeterminado - (ID) que llama a su inicializador designado.

Para los nombres de todos estos, me aseguraría de usar siempre un nombre más descriptivo. Probablemente está bien en un ejemplo tan simple para usar A1, X, Y, etc., pero para cualquier cosa más complicada, use nombres que describan con más detalle exactamente cuál es la variable.

En el método de descripción, parece que está llamando a los valores int con% d. No puedo pensar en una razón para no usar% I, pero tal vez estoy equivocado aquí.

Una última cosa, en la interfaz, el espaciado dentro de la Declaración de - (ID) initwithetc está suelto. Sin embargo, parece correcta en la implementación.

 

This is my first review so bear that in mind when you are reading it.

The first thing I see is that in the initialization, you should not use the automatic setters and getters for properties. The reason for this is that the object may not be completely initialized, and thus may fail. So instead of doing:

self.a1 = x; self.a2 = s; self.a3 = y; 

access the properties directly like so:

_a1 = x;  _a2 = s; _a3 = y; 

Otherwise, your init pattern is good, and bonus points for having a default -(id)init that calls your designated initializer.

For the names of all of these, I would make sure to always use a more descriptive name. It is probably okay in such a simple example to use a1, x, y, etc, but for anything more complicated, use names that describe in more detail exactly what the variable is.

In the description method it looks like you are calling the int values with %d. I can't think of a reason not to use %i, but maybe I am wrong here.

One last thing, in the interface the spacing inside the declaration of -(id)initWithEtc is loose. It looks correct in the implementation though.

 
 
 
 
4
 
vote

Parte C de la asignación es un poco extrañamente redactado y un tipo de ambiguo. Sin embargo, mi mejor conjetura es que la parte C está hablando de los métodos de fábrica . Los métodos de fábrica son los métodos de clase que puede llamar, lo que devuelve una instancia de la clase.

en lugar de llamar:

  Foo *foo = [[Foo alloc] init];   

Un método de fábrica nos permitiría llamar simplemente:

  Foo *foo = [Foo foo];   

En lo que a mí respecta, ninguna clase está completa sin métodos de fábrica. Aconsejaría al menos un método de fábrica por init , y en algunos casos, más métodos de fábrica que init MÉTODOS.

En este caso, los métodos de fábrica para la clase A se verían así:

  + (instancetype)classA {     return [[self alloc] init]; }  + (instancetype)classAWithA1:(int)x andA2:(NSString *)s andA3:(int)y {     return [[self alloc] initWithA1:x andA2:s andA3:y]; }   

Desde aquí, cómo crea métodos de fábrica debe ser bastante explicativo. Envuelve la llamada a alloc dentro del método y simplemente devuelva el resultado de llamar a uno de sus métodos 9988776665544336 .

Ahora puede simplemente crear una instancia de su clase como tal:

  ClassA *a = [ClassA classAWithA1:1 andA2:@"hello" andA3:1];   
 

Part C of the assignment is a little oddly worded and kind of ambiguous. My best guess however is that part C is talking about factory methods. Factory methods are class methods you can call which return an instance of the class.

Rather than calling:

Foo *foo = [[Foo alloc] init]; 

A factory method would allow us to call simply:

Foo *foo = [Foo foo]; 

As far as I'm concerned, no class is complete without factory methods. I'd advise at least one factory method per init method, and in some cases, more factory methods than init methods.

In this case, the factory methods for class A would look like this:

+ (instancetype)classA {     return [[self alloc] init]; }  + (instancetype)classAWithA1:(int)x andA2:(NSString *)s andA3:(int)y {     return [[self alloc] initWithA1:x andA2:s andA3:y]; } 

From here, how you create factory methods should be pretty self-explanatory. You wrap the call to alloc within the method and simply return the result of calling one of your init methods.

Now you can simply instantiate your class as such:

ClassA *a = [ClassA classAWithA1:1 andA2:@"hello" andA3:1]; 
 
 

Relacionados problema

0  Patrón de módulo revelador modificado para mayor comportamiento similar a la clase  ( Revealing module pattern modified for more class like behavior ) 
Recientemente he estado aprendiendo sobre el patrón de revelación del módulo, y parece que una forma realmente buena de estructurar el código en muchos casos....

2  Sistema de entrega de pizza  ( Pizza delivery system ) 
He hecho este código como My Summers Vacation Project en Turbo C ++ (conozco que es viejo y desactualizado, pero eso es lo que nos enseñan en nuestra escuela)...

4  Insertando y mostrando libros  ( Inserting and displaying books ) 
Estoy tratando de escribir un programa donde puede insertar y mostrar algunos libros (sin usar una base de datos). por hacer esto, uso tres clases: Book...

7  Clases de armadura y arma para un juego  ( Armor and weapon classes for a game ) 
Tengo una false0 false1 en My Game, que hereda de la clase abstracta false2 : false3 Luego tengo una clase false4 que no es más que un botón, con ...

6  Implementación de herencia simple y rápida en JavaScript  ( Implementing simple and fast inheritance in javascript ) 
He estado usando la John Resig Javascript Class Implementación en Mis aplicaciones web, Pero las pruebas muestran que es realmente lento. Realmente me parec...

3  dnaof () - Herencia hecha fácil, mi propia herramienta de herencia  ( Dnaof inheritance made easy my own make inheritance tool ) 
https://github.com/exebook/dnaof He creado esta simple herramienta de herencia para JavaScript, ¿podría alguien con un conocimiento profundo en la herenci...

3  Usando composición en lugar de herencia  ( Using composition instead of inheritance ) 
He estado usando la entidad Marco 6, API AUTOMAPTER, ASP.NET WEB y golpee algunos problemas en el camino, cada vez que se recomendó que pudiera cambiar mi cód...

8  Grabadora para eventos de teclado y ratón  ( Recorder for keyboard and mouse events ) 
Estoy construyendo una grabadora de eventos. Hasta ahora, el código se ve limpio, pero siento que me falta algo que puede hacer que este código sea aún mejor....

3  Creando clases de vectores matemáticos N-dimensionales a través de la herencia  ( Creating n dimensional mathematical vector classes through inheritance ) 
Ahora mismo no tengo conocimiento de las plantillas, pero acabo de terminar de aprender sobre la herencia, y quería aplicarlo a una clase 99887766655544333 ...

2  ¿Está mi código sobreseñado? ¿Confíe demasiado en las interfaces? [cerrado]  ( Is my code overdesigned does it rely too heavily on interfaces ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos