υπερφόρτωση Κατασκευαστής στη γραφομηχανή

ψήφοι
216

Έχει κανείς κάνει κατασκευαστή υπερφόρτωση στη γραφομηχανή. Στη σελίδα 64 των προδιαγραφών γλώσσας (v 0.8), υπάρχουν καταστάσεις που περιγράφει υπερφόρτωση κατασκευαστή, αλλά δεν υπήρχε καμία δείγμα κώδικα δεδομένη.

Προσπαθώ ένα πολύ βασικό δήλωση της κλάσης αυτή τη στιγμή? μοιάζει με αυτό,

interface IBox {    
    x : number;
    y : number;
    height : number;
    width : number;
}

class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;

    constructor(obj: IBox) {    
        this.x = obj.x;
        this.y = obj.y;
        this.height = obj.height;
        this.width = obj.width;
    }   

    constructor() {
        this.x = 0;
        this.y = 0;
        this.width = 0;
        this.height = 0;
    }
}

Όταν έτρεξε με BoxSample.ts TSC, ρίχνει μια διπλούν ορισμό κατασκευαστή - η οποία είναι προφανής. Κάθε βοήθεια είναι ευπρόσδεκτη.

Δημοσιεύθηκε 03/10/2012 στις 06:48
πηγή χρήστη
Σε άλλες γλώσσες...                            


13 απαντήσεις

ψήφοι
190

Γραφομηχανή σας επιτρέπει να κηρύξει υπερφόρτωση, αλλά μπορείτε να έχετε μόνο μία εφαρμογή και ότι η εφαρμογή πρέπει να έχει μια υπογραφή που είναι συμβατό με όλες τις υπερφορτώσεις. Στο παράδειγμά σας, αυτό μπορεί να γίνει εύκολα με μια προαιρετική παράμετρο όπως,

interface IBox {    
    x : number;
    y : number;
    height : number;
    width : number;
}

class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;

    constructor(obj?: IBox) {    
        this.x = obj && obj.x || 0
        this.y = obj && obj.y || 0
        this.height = obj && obj.height || 0
        this.width = obj && obj.width || 0;
    }   
}

ή δύο υπερφορτίσεις με μια γενικότερη κατασκευαστή όπως και στο,

interface IBox {    
    x : number;
    y : number;
    height : number;
    width : number;
}

class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;

    constructor();
    constructor(obj: IBox); 
    constructor(obj?: any) {    
        this.x = obj && obj.x || 0
        this.y = obj && obj.y || 0
        this.height = obj && obj.height || 0
        this.width = obj && obj.width || 0;
    }   
}
Απαντήθηκε 03/10/2012 στις 07:14
πηγή χρήστη

ψήφοι
63

Σημειώστε ότι μπορείτε να αντιμετωπίσετε την έλλειψη της υπερφόρτωσης στο επίπεδο εφαρμογής μέσω προεπιλεγμένες παραμέτρους στη γραφομηχανή, για παράδειγμα:

interface IBox {    
    x : number;
    y : number;
    height : number;
    width : number;
}

class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;

    constructor(obj : IBox = {x:0,y:0, height:0, width:0}) {    
        this.x = obj.x;
        this.y = obj.y;
        this.height = obj.height;
        this.width = obj.width;
    }   
}

Επεξεργασία: Από πέμπτης Δεκεμβρίου '16, δείτε την απάντηση Benson είναι για μια πιο εμπεριστατωμένη λύση που επιτρέπει μεγαλύτερη ευελιξία.

Απαντήθηκε 09/10/2012 στις 07:29
πηγή χρήστη

ψήφοι
48

Όσον αφορά κατασκευαστή επιβαρύνει μια εναλλακτική λύση θα ήταν να εφαρμόσει το πρόσθετο υπερφορτώσεις και στατικές μεθόδους εργοστάσιο . Νομίζω ότι του πιο κατανοητή και λιγότερο σύγχυση από τη δοκιμή επιχειρήματα κλήση σας. Εδώ είναι ένα απλό παράδειγμα:

class Person {
    static fromData(data: PersonData) {
        let { first, last, birthday, gender = 'M' } = data 
        return new this(
            `${last}, ${first}`,
            calculateAge(birthday),
            gender
        )
    }

    constructor(
        public fullName: string,
        public age: number,
        public gender: 'M' | 'F'
    ) {}
}

interface PersonData {
    first: string
    last: string
    birthday: string
    gender?: 'M' | 'F'
}


let personA = new Person('Doe, John', 31, 'M')
let personB = Person.fromData({
    first: 'John',
    last: 'Doe',
    birthday: '10-09-1986'
})

Μέθοδος υπερφόρτωση στη γραφομηχανή , δεν είναι πραγματικό , ας πούμε, όπως θα απαιτούσε πάρα πολύ κώδικα compiler που δημιουργείται και την ομάδα πυρήνα προσπαθήστε να αποφύγετε ότι με κάθε κόστος. Επί του παρόντος, ο κύριος λόγος για τη μέθοδο υπερφόρτωση για να είναι παρόντες για τη γλώσσα είναι να παρέχει έναν τρόπο για να γράψει δηλώσεις για τις βιβλιοθήκες με τη μαγεία επιχειρήματα API τους. Από τη στιγμή που θα χρειαστεί να κάνει όλη τη βαριά ανύψωση από τον εαυτό σας να χειριστεί διαφορετικά σύνολα επιχειρημάτων δεν βλέπω πολλά πλεονεκτήματα στη χρήση υπερφορτώσεις αντί χωρίζονται μεθόδους.

Απαντήθηκε 31/07/2016 στις 21:08
πηγή χρήστη

ψήφοι
38

Σημείωση: αυτή απλοποιήθηκε και ενημέρωση 13/04/2017 να αντικατοπτρίζουν γραφομηχανή 2.1, δείτε το ιστορικό για γραφομηχανή 1.8 απάντηση.

Ακούγεται σαν να θέλετε η παράμετρος αντικείμενο να είναι προαιρετική, καθώς επίσης και κάθε μία από τις ιδιότητες του αντικειμένου να είναι προαιρετική. Στο παράδειγμα, όπως προβλέπεται, σύνταξη υπερφόρτωσης δεν είναι απαραίτητη. Ήθελα να επισημάνω κάποιες κακές πρακτικές στον κάποιες από τις απαντήσεις εδώ. Σύμφωνοι, δεν είναι η μικρότερη δυνατή έκφραση ουσιαστικά γραφής box = { x: 0, y: 87, width: 4, height: 0 }, αλλά αυτό παρέχει όλες τις υπαινίχθηκε λεπτότητα κώδικα που θα μπορούσε ενδεχομένως να θέλουν από την τάξη, όπως περιγράφεται. Αυτό το παράδειγμα σας επιτρέπει να καλέσετε μια συνάρτηση με μία, κάποια, όλα, ή καμία από τις παραμέτρους και να πάρετε ακόμα προκαθορισμένες τιμές.

 /** @class */
 class Box {
     public x?: number;
     public y?: number;
     public height?: number;
     public width?: number;     

     // The class can work double-duty as the interface here since they are identical
     // Alternately, reference your own interface, e.g.:  `...BoxI = {} as BoxI` 
     constructor(obj: Box = {} as Box) {

         // Define the properties of the incoming `obj` object here. 
         // Setting a default value with the `= 0` syntax is optional for each parameter
         let {
             x = 0,
             y = 0,
             height = 0,
             width = 0
         } = obj;

         /** Use jsdoc comments here for inline ide auto-documentation */
         this.x = x;
         this.y = y;
         this.height = height;
         this.width = width;
     }
 }

Αυτή είναι μια πολύ ασφαλής τρόπος για να γράψει για τις παραμέτρους που μπορεί να μην έχουν όλες τις ιδιότητες του αντικειμένου ορίζεται. Τώρα μπορείτε να γράψετε με ασφάλεια οποιοδήποτε από αυτά:

const box1 = new Box();
const box2 = new Box({});
const box3 = new Box({x:0});
const box4 = new Box({x:0, height:10});
const box5 = new Box({x:0, y:87,width:4,height:0});

 // Correctly reports error in TypeScript, and in js, box6.z is undefined
const box6 = new Box({z:0});  

Καταρτίζονται, θα δείτε ότι οι προαιρετικές παραμέτρους πραγματικά είναι προαιρετικές, που αποφεύγει τις παγίδες ενός ευρέως χρησιμοποιείται (αλλά επιρρεπής σε λάθη) εναλλακτική σύνταξη var = isOptional || default;από τον έλεγχο κατά void 0, το οποίο είναι συντομογραφία για undefined:

Η Καταρτίζονται εξόδου

var Box = (function () {
    function Box(obj) {
        if (obj === void 0) { obj = {}; }
        var _a = obj.x, 
        x = _a === void 0 ? 1 : _a,
        _b = obj.y,
        y = _b === void 0 ? 1 : _b,
        _c = obj.height,
        height = _c === void 0 ? 1 : _c,
        _d = obj.width,
        width = _d === void 0 ? 1 : _d;
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
    }
    return Box;
}());

Προσθήκη: Ρύθμιση προεπιλεγμένες τιμές: με λάθος τρόπο

Η ||(ή) χειριστή

Σκεφτείτε τον κίνδυνο ||ή / και φορέων κατά τη ρύθμιση προεπιλεγμένες εναλλακτικές τιμές, όπως φαίνεται σε κάποιες άλλες απαντήσεις. Παρακάτω Αυτός ο κωδικός απεικονίζει τη λάθος τρόπος για να ορίσετε προεπιλογές. Μπορείτε να πάρετε μη αναμενόμενα αποτελέσματα κατά την αξιολόγηση κατά falsey αξίες όπως 0, «», null, απροσδιόριστο, ψευδή, NaN:

var myDesiredValue = 0;
var result = myDesiredValue || 2;

// This test will correctly report a problem with this setup.
console.assert(myDesiredValue === result && result === 0, 'Result should equal myDesiredValue. ' + myDesiredValue + ' does not equal ' + result);

Object.assign (αυτό, obj)

Στις δοκιμές μου, χρησιμοποιώντας ES6 / γραφομηχανή αποδομείται αντικείμενο μπορεί να είναι σχεδόν 90% πιο γρήγορα από ό, τι Object.assign . Χρησιμοποιώντας ένα αποδομημένο η παράμετρος επιτρέπει μόνο τις μεθόδους και τις ιδιότητες που έχετε εκχωρήσει στο αντικείμενο. Για παράδειγμα, θεωρούν αυτή τη μέθοδο:

class BoxTest {
    public x?: number = 1;

    constructor(obj: BoxTest = {} as BoxTest) {
        Object.assign(this, obj);
    }
}

Αν κάποιος άλλος χρήστης δεν χρησιμοποιούσε γραφομηχανή και προσπάθησε να τοποθετήσει μια παράμετρο που δεν ανήκουν, για παράδειγμα, θα μπορούσαν να δοκιμάστε να βάλετε ένα zακίνητο

var box = new BoxTest({x: 0, y: 87, width: 4, height: 0, z: 7});

// This test will correctly report an error with this setup. `z` was defined even though `z` is not an allowed property of obj.
console.assert(typeof box.z === 'undefined')
Απαντήθηκε 05/12/2016 στις 14:30
πηγή χρήστη

ψήφοι
32

Ξέρω ότι αυτό είναι ένα παλιό θέμα, αλλά τα νέα στο 1.4 είναι οι τύποι ένωση? χρησιμοποιούν αυτά για όλες τις υπερφορτώσεις λειτουργίας (συμπεριλαμβανομένων κατασκευαστών). Παράδειγμα:

class foo {
    private _name: any;
    constructor(name: string | number) {
        this._name = name;
    }
}
var f1 = new foo("bar");
var f2 = new foo(1);
Απαντήθηκε 04/02/2015 στις 18:28
πηγή χρήστη

ψήφοι
20

Ενημέρωση (8 Ιουνίου 2017): guyarad και snolflake κάνουν ισχύει σημεία στα σχόλιά τους κάτω από την απάντησή μου. Θα ήθελα να συστήσω στους αναγνώστες δείτε τις απαντήσεις από Benson , Joe και snolflake που έχουν καλύτερες απαντήσεις από τη δική μου.

Αρχικό Απάντηση (27 Ιανουαρίου, 2014)

Ένα άλλο παράδειγμα του πώς μπορεί να επιτευχθεί κατασκευαστή υπερφόρτωση:

class DateHour {

  private date: Date;
  private relativeHour: number;

  constructor(year: number, month: number, day: number, relativeHour: number);
  constructor(date: Date, relativeHour: number);
  constructor(dateOrYear: any, monthOrRelativeHour: number, day?: number, relativeHour?: number) {
    if (typeof dateOrYear === "number") {
      this.date = new Date(dateOrYear, monthOrRelativeHour, day);
      this.relativeHour = relativeHour;
    } else {
      var date = <Date> dateOrYear;
      this.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
      this.relativeHour = monthOrRelativeHour;
    }
  }
}

Πηγή: http://mimosite.com/blog/post/2013/04/08/Overloading-in-TypeScript

Απαντήθηκε 27/01/2014 στις 17:02
πηγή χρήστη

ψήφοι
3

Σε περίπτωση που ένα προαιρετικό, δακτυλογραφημένη η παράμετρος είναι αρκετά καλή, εξετάστε το ακόλουθο κώδικα που επιτυγχάνει το ίδιο χωρίς επανάληψη των ιδιοτήτων ή ορίζει μια διεπαφή:

export class Track {
   public title: string;
   public artist: string;
   public lyrics: string;

   constructor(track?: Track) {
     Object.assign(this, track);
   }
}

Λάβετε υπόψη αυτό θα εκχωρήσει όλες τις ιδιότητες που ψηφίστηκε το track, παραμονή και αν δεν ορίζεται στο Track.

Απαντήθηκε 06/11/2016 στις 00:22
πηγή χρήστη

ψήφοι
1

Μπορείτε να χειριστείτε αυτό με:

import { assign } from 'lodash'; // if you don't have lodash use Object.assign
class Box {
    x: number;
    y: number;
    height: number;
    width: number;
    constructor(obj: Partial<Box> = {}) {    
         assign(this, obj);
    }
}

Μερική θα κάνει τα πεδία σας (x, y, πλάτος, ύψος) προαιρετικών, επιτρέποντας πολλαπλές κατασκευαστές

π.χ: μπορείτε να το κάνετε new Box({x,y})χωρίς το ύψος και το πλάτος.

Η = {}θα χειριστεί falsy αξίας, όπως απροσδιόριστη, null κ.λπ., και, στη συνέχεια, μπορείτε να κάνετεnew Box()

Απαντήθηκε 11/09/2018 στις 09:36
πηγή χρήστη

ψήφοι
1

Μια άλλη εκδοχή, όπως στον κώδικα @ ShinNoNoir του, χρησιμοποιώντας τις προκαθορισμένες τιμές και τη σύνταξη εξάπλωση:

class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;

    constructor({x, y, height, width}: IBox = { x: 0, y: 0, height: 0, width: 0 }) {
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;
    }
}
Απαντήθηκε 30/11/2016 στις 05:11
πηγή χρήστη

ψήφοι
0

Μπορώ να χρησιμοποιήσω την ακόλουθη εναλλακτική λύση για να πάρει default / προαιρετικό params και «είδος-του-υπερφορτωμένο» κατασκευαστές με μεταβλητό αριθμό των params:

private x?: number;
private y?: number;

constructor({x = 10, y}: {x?: number, y?: number}) {
 this.x = x;
 this.y = y;
}

Ξέρω ότι δεν είναι η ομορφότερη κωδικό ποτέ, αλλά ένα συνηθίσει σε αυτό. Δεν υπάρχει ανάγκη για την πρόσθετη διεπαφή και επιτρέπει ιδιωτικά μέλη, τα οποία δεν είναι δυνατή κατά τη χρήση της διεπαφής.

Απαντήθηκε 20/09/2019 στις 14:28
πηγή χρήστη

ψήφοι
0

Στην πραγματικότητα θα μπορούσε να είναι πολύ αργά γι 'αυτή την απάντηση, αλλά τώρα μπορείτε να το κάνετε αυτό:

class Box {
    public x: number;
    public y: number;
    public height: number;
    public width: number;

    constructor();
    constructor(obj: IBox);
    constructor(obj?: IBox) {    
        this.x = !obj ? 0 : obj.x;
        this.y = !obj ? 0 : obj.y;
        this.height = !obj ? 0 : obj.height;
        this.width = !obj ? 0 : obj.width;
    }
}

Έτσι, αντί να στατικές μεθόδους που μπορείτε να κάνετε το παραπάνω. Ελπίζω ότι θα σας βοηθήσει !!!

Απαντήθηκε 26/05/2019 στις 23:31
πηγή χρήστη

ψήφοι
0

Μπορούμε να προσομοιώσει την υπερφόρτωση κατασκευαστή χρησιμοποιώντας φύλακες

interface IUser {
  name: string;
  lastName: string;
}

interface IUserRaw {
  UserName: string;
  UserLastName: string;
}

function isUserRaw(user): user is IUserRaw {
  return !!(user.UserName && user.UserLastName);
}

class User {
  name: string;
  lastName: string;

  constructor(data: IUser | IUserRaw) {
    if (isUserRaw(data)) {
      this.name = data.UserName;
      this.lastName = data.UserLastName;
    } else {
      this.name = data.name;
      this.lastName = data.lastName;
    }
  }
}

const user  = new User({ name: "Jhon", lastName: "Doe" })
const user2 = new User({ UserName: "Jhon", UserLastName: "Doe" })
Απαντήθηκε 27/03/2019 στις 00:18
πηγή χρήστη

ψήφοι
0

Θα πρέπει να είχε στο μυαλό του αυτό το ...

contructor ()

κατασκευαστή (α: οποιοδήποτε, b: οποιαδήποτε, c: υπάρχει)

Είναι το ίδιο του

νέα () ή νέα ( "a", "b", "c")

Ετσι

κατασκευαστή (α:; οποιαδήποτε, β:; οποιαδήποτε, γ:; υπάρχει) είναι η παραπάνω ίδιο και είναι πιο ευέλικτη ...

νέα () ή νέα ( "α") ή νέα ( "a", "b") ή νέα ( "a", "b", "c")

Απαντήθηκε 02/06/2018 στις 14:15
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more