2016-11-15 1 views
2

Je souhaite dériver une classe dans swift 3 de la classe Measurement afin de pouvoir ajouter des fonctionnalités supplémentaires pour définir une unité par défaut "Impérial" et "Métrique" pour chaque mesure. Comment puis-je faire cela? Voici comment j'ai commencé.Comment dériver une classe à partir de la mesure dans Swift

enum UnitOptions { case imperial, metric } 

class CustomMeasurement : Measurement { 

    let imperialUnit: Unit 
    let metricUnit: Unit 
    let inputMeasurement = Measurement<Unit> 

    init(value: Double, inputUnit: Unit, imperialUnit: Unit, metricUnit: Unit) { 
     self.imperialUnit = imperialUnit 
     self.metricUnit = metricUnit 

     inputMeasurement = Measurement<Unit>(value: value, unit: inputUnit) 
    } 

    func getMeasurement(unitSystem: UnitOptions) { 
     if (unitSystem == .imperial) { 
      return inputMeasurement.converted(to: imperialUnit) 
     } else { 
      return inputMeasurement.converted(to: metricUnit) 
     } 
    } 
} 

Répondre

3

Vous souhaitez créer une extension. Ce que vous avez commencé à faire ici est en train de définir une sous-classe. La mesure est en fait un ModelType et non une classe https://developer.apple.com/reference/foundation/measurement (bien que, je ne suis pas sûr à 100% si dans Swift ModelTypes sont juste un type de classe de toute façon, donc cela pourrait ne pas importer).

Mais pour répondre à la question, il y a en fait beaucoup de types intégrés qui font déjà des conversions, donc je ne suis pas strictement sûr que vous ayez besoin de faire ce que vous demandez. Quelle est la version impériale de Centimètres? Est-ce que c'est des pouces ou des pieds? Quelle est la version impériale de Millimètres?

Sans extensions, voici ce que vous pouvez faire:

let testInch : Measurement = Measurement(value: 25, unit: UnitLength.inches) 
let testCM : Measurement = Measurement(value: 10, unit: UnitLength.centimeters) 
var testInMetres = (testInch + testCM).converted(to: UnitLength.meters) 

Définir les choses comme une mesure, avec une unité, vous pouvez ajouter, soustraire les etc., sans aucune pénalité et puis juste les utiliser comme vous comme plus tard.

Si vous voulez avoir une "impériale" de type, je ferais quelque chose comme ceci:

extension UnitLength { 
    static var imperial: UnitLength { 
     switch self.baseUnit() { 
     case centimeters: 
      return UnitLength.inches 
     case meters: 
      return UnitLength.feet 
     default: 
      return UnitLength.inches 
     } 
    } 
} 

Nous étendons le type unitlength d'inclure un nouveau type "Imperial". Tout ce qu'il fait est de vérifier le type de base, s'il s'agit de Centimètres, renvoie le type en pouces, si c'est mètres, utilise pieds, ou par défaut en pouces. Vous pouvez définir un traitement personnalisé de toutes sortes de UnitTypes pour "Imperial" ici comme vous le souhaitez.

utiliser comme ceci:

testInMetres.convert(to: UnitLength.imperial) // Returns length in feet. 

Je ne l'ai pas utilisé avant la mesure, ce poste était vraiment utile en arrière-plan. https://oleb.net/blog/2016/07/measurements-and-units/

0

Je suis en retard au thread, mais une autre façon, que je pense peut-être préférable, est d'étendre une sous-classe (ou dans votre cas, de nombreuses sous-classes) de Dimension. Par exemple, voici comment vous ajoutez une nouvelle unité, mm/heure, à la classe UnitSpeed:

extension UnitSpeed { 
    @nonobjc static let mmPerHour = UnitSpeed(symbol: "mm/hr", converter: UnitConverterLinear(coefficient: 1000.0*3600.0)) 
} 

Vous pouvez ajouter une place @nonobjc static let imperial = milesPerHour variable.

Plus d'infos sur Dimension.