рдирдорд╕реНрдХрд╛рд░, рдореЗрд░рд╛ рдирд╛рдо рджрд┐рдорд┐рддреНрд░реА рдХрд╛рд░реНрд▓реЛрд╡реНрд╕реНрдХреА рд╣реИ рдФрд░ рдореИрдВ ... рдореИрдВ рдЖрдкрдХреЛ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдХреА рдореВрд▓рднреВрдд рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬреЛ рдЕрдХреНрд╕рд░ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рднрд╛рд╖рд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдкреНрд░рд┐рдЬреНрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ рд╕рдордЭрддрд╛ рд╣реИ, рдЬреЛ рд╡рд┐рдХрд╛рд╕рд╡рд╛рджреА рд╡рд┐рдХрд╛рд╕ рдХреЗ рдХрд╛рд░рдг рдХрдИ atavism рд╣реИред рдЗрд╕рд▓рд┐рдП, рднрд▓реЗ рд╣реА рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ "рднрд┐рдиреНрдирддрд╛" рдХреНрдпрд╛ рд╣реИ, рдореБрджреНрджреЛрдВ рдХреЛ рдирдП рд╕рд┐рд░реЗ рд╕реЗ рджреЗрдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВред рд╣рдо рдмрд╣реБрдд рдмреБрдирд┐рдпрд╛рджреА рдмрд╛рддреЛрдВ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдПрдХ рд╢реБрд░реБрдЖрдд рднреА рд╕рдм рдХреБрдЫ рд╕рдордЭ рдЬрд╛рдПрдЧреАред рдФрд░ рд╣рдо рдкрд╛рдиреА рдХреЗ рдмрд┐рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдЙрдирдХреЗ рдЬреНрдЮрд╛рди рдХреЛ рд╕рдВрд░рдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛред рдХреЛрдб рдЙрджрд╛рд╣рд░рдг рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рдорд╛рди рдПрдХ рдЫрджреНрдо рднрд╛рд╖рд╛ рдореЗрдВ рд╣реЛрдЧрд╛ред рдлрд┐рд░ рдХрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рдПрдЧреАред рдФрд░ рдЕрдЧрд░ рдЖрдк рдЕрдкрдиреА рднрд╛рд╖рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреЛ рдХрд┐рд╕реА рдФрд░ рдХреА рд░реЗрдХ рдкрд░ рдХрджрдо рдирд╣реАрдВ рд░рдЦрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рддрд░реНрдХ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░
рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╣ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдЙрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕реЗрдЯ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг:
// function log( id : string | number ) {} // class Logger { constructor( readonly id : Natural ) {} } // class Node< Id extends Number > { id : Id }
рдПрдХ рддрд░реНрдХ рдЬреЛ рд╣рдо рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рд╕рдордп, рддрд░реНрдХ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рд╣реЛрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ, рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣реА рд╡рдЬрд╣ рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рдХ рдлрд┐рд░ рд╕реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг:
log( 123 ) // new Logger( promptStringOrNumber( 'Enter id' ) ) // new Node( 'root' ) // ,
рдЙрдкрдкреНрд░рдХрд╛рд░
рдкреНрд░рдХрд╛рд░ рдПрдХ рдкрджрд╛рдиреБрдХреНрд░рдо рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рдПрдХ рд╕реБрдкрд░рдкрд╛рдЗрдк рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рд╣реИред рдПрдХ рд╕реБрдкрд░-рдЯрд╛рдЗрдк рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЛ рд╕рдВрдХреАрд░реНрдг рдХрд░рдХреЗ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рдХрд╛ рдЧрдарди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рд╛рдХреГрддрд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреВрд░реНрдгрд╛рдВрдХ рдФрд░ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдХрд╛ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реИред рдФрд░ рддреАрдиреЛрдВ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд░рд┐рдпрд▓ рдХреЗ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реИрдВред рдФрд░ рдкреНрд░рдзрд╛рди рдкреНрд░рдХрд╛рд░ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдХрд╛ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реИред рдЙрд╕реА рд╕рдордп, рд╕рдХрд╛рд░рд╛рддреНрдордХ рдФрд░ рдкреВрд░реНрдгрд╛рдВрдХ рдкреНрд░рдХрд╛рд░ рдЕрддрд┐рд╡реНрдпрд╛рдкреА рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рджреВрд╕рд░реЗ рдХреЛ рд╕рдВрдХреБрдЪрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рдмрдирд╛рдиреЗ рдХрд╛ рджреВрд╕рд░рд╛ рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рджреВрд╕рд░реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдСрд░реНрдереЛрдЧреЛрдирд▓ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рдХрд░ рдЗрд╕рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдВрдкрддреНрддрд┐ "рд░рдВрдЧ" рдХреЗ рд╕рд╛рде рдПрдХ "рд░рдВрдЧ рдЖрдВрдХрдбрд╝рд╛" рд╣реИ, рдФрд░ рд╕рдВрдкрддреНрддрд┐ "рдКрдВрдЪрд╛рдИ" рдХреЗ рд╕рд╛рде рдПрдХ "рд╡рд░реНрдЧ" рд╣реИред рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рдВрдпреЛрдЬрди рд╕реЗ рд╣рдореЗрдВ рдПрдХ "рд░рдВрдЧ рд╡рд░реНрдЧ" рдорд┐рд▓рддрд╛ рд╣реИред рдФрд░ рдЗрд╕рдХреЗ "рддреНрд░рд┐рдЬреНрдпрд╛" рдХреЗ рд╕рд╛рде рдПрдХ "рд╕рд░реНрдХрд▓" рдЬреЛрдбрд╝рдХрд░ рд╣рдо рдПрдХ "рд░рдВрдЧ рд╕рд┐рд▓реЗрдВрдбрд░" рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдиреБрдХреНрд░рдо
рдЖрдЧреЗ рдХреЗ рдХрдерди рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЬрд╛рдирд╡рд░реЛрдВ рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рдкрджрд╛рдиреБрдХреНрд░рдо рдФрд░ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рдорд╛рди рдкрджрд╛рдиреБрдХреНрд░рдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
abstract class Animal {} abstract class Pet extends Animal {} class Cat extends Pet {} class Dog extends Pet {} class Fox extends Animal {} class AnimalCage { content : Animal } class PetCage extends AnimalCage { content : Pet } class CatCage extends PetCage { content : Cat } class DogCage extends PetCage { content : Dog } class FoxCage extends AnimalCage { content : Fox }
рдиреАрдЪреЗ рд╕рдм рдХреБрдЫ рдКрдкрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╕рдВрдХреБрдЪрди рд╣реИред рдПрдХ рдкрд╛рд▓рддреВ рдЬрд╛рдирд╡рд░ рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдореЗрдВ рдХреЗрд╡рд▓ рдШрд░реЗрд▓реВ рдЬрд╛рдирд╡рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЬрдВрдЧрд▓реА рдЬрд╛рдирд╡рд░ рдирд╣реАрдВред рдПрдХ рдХреБрддреНрддреЗ рдХреЗ рд╕рд╛рде рдПрдХ рдкрд┐рдВрдЬрд░реЗ рдореЗрдВ рдХреЗрд╡рд▓ рдХреБрддреНрддреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рд╣рдкреНрд░рд╕рд░рдг
рд╕рдмрд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕рдмрд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╕реБрдкрд░рдЯреЗрдк рдпрд╛ рдХреЛрд╡рд░рд┐рдпрди рдХрд╛ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИ ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕рд╣рд╕рдВрдпреЛрдЬрдХ рд╣реИред рдпрд╣реА рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡рдпрдВ рдФрд░ рдЗрд╕рдХреЗ рдХрд┐рд╕реА рднреА рдЙрдкрдкреНрд░рдХрд╛рд░ рджреЛрдиреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реБрдкрд░рдкреЗрдкреНрд╕ рдпрд╛ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
function touchPet( cage : PetCage ) : void { log( `touch ${cage.content}` ) } touchPet( new AnimalCage ) // forbid touchPet( new PetCage ) // allow touchPet( new CatCage ) // allow touchPet( new DogCage ) // allow touchPet( new FoxCage ) // forbid

рдЪреВрдВрдХрд┐ рд╣рдо рдкрд┐рдВрдЬрд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рддреЗ рд╣реИрдВ, рд╣рдо рдмрд┐рд▓реНрд▓реА рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдкрд╛рд▓рддреВ рдЬрд╛рдирд╡рд░ рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдХреЗ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реИред
contravariant
рдЙрдкрдкреНрд░рдХрд╛рд░ рдкреНрд░рддрд┐рдмрдВрдз рдпрд╛ рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕ рдХреЛ рд╕рдордЭрдирд╛ рдереЛрдбрд╝рд╛ рдХрдард┐рди рд╣реИред рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реИред рдпрд╣реА рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡рдпрдВ рдФрд░ рдЗрд╕рдХреЗ рдХрд┐рд╕реА рднреА рд╕реБрдкрд░рдЯреЗрдк рджреЛрдиреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдкрдкреНрд░рдХрд╛рд░ рдпрд╛ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
function pushPet( cage : PetCage ) : void { const Pet = random() > .5 ? Cat : Dog cage.content = new Pet } pushPet( new AnimalCage ) // allow pushPet( new PetCage ) // allow pushPet( new CatCage ) // forbid pushPet( new DogCage ) // forbid pushPet( new FoxCage ) // forbid

рд╣рдо рдмрд┐рд▓реНрд▓реА рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдХреЛ рдкрд╛рд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреБрддреНрддреЗ рдХреЛ рд╡рд╣рд╛рдВ рдбрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдЕрдиреБрдореЗрдп рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рднреА рдЬрд╛рдирд╡рд░ рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдмрд┐рд▓реНрд▓реА рдФрд░ рдХреБрддреНрддреЗ рджреЛрдиреЛрдВ рдХреЛ рд╡рд╣рд╛рдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдирд┐рд╢реНрдЪрд░рддрд╛
рд╕рдмрдЯрд╛рдЗрдк рдФрд░ рд╕реБрдкрд░рдкрд╛рдЗрдк рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдирд╛ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рдЖрдХреНрд░рдордг рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИред рдпрд╣реА рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЕрдзрд┐рдХ рдирд╣реАрдВред
function replacePet( cage : PetCage ) : void { touchPet( cage ) pushPet( cage ) } replacePet( new AnimalCage ) // forbid replacePet( new PetCage ) // allow replacePet( new CatCage ) // forbid replacePet( new DogCage ) // forbid replacePet( new FoxCage ) // forbid

replacePet
рдлрд╝рдВрдХреНрд╢рди рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЛ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: рдпрд╣ pushPet
рд╕реЗ рдкреНрд░рдХрд╛рд░ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз, рдФрд░ pushPet
рджреНрд╡рд╛рд░рд╛ рдЙрдкрдкреНрд░рдХрд╛рд░ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз pushPet
ред рдпрджрд┐ рд╣рдо рдЙрд╕реЗ рдХрд┐рд╕реА рднреА рдЬрд╛рдирд╡рд░ рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░рд╛ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рд╡рд╣ рдЙрд╕реЗ рдЯрдЪрдкреЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдЧрд╛, рдЬреЛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рд▓реЛрдордбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдП (рдПрдХ рдЬрдВрдЧрд▓реА рдЬрд╛рдирд╡рд░ рдмрд╕ рдПрдХ рдЙрдВрдЧрд▓реА рдХрд╛рдЯ рджреЗрдЧрд╛)ред рдФрд░ рдЕрдЧрд░ рд╣рдо рдмрд┐рд▓реНрд▓реА рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ pushPet
рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
bivariant
рд▓реЗрдХрд┐рди рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреА рд╡рд┐рджреЗрд╢реА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рджреНрд╡реИрдзред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЙрдкрдкреНрд░рдХрд╛рд░ рдпрд╛ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╣реИред
function enshurePet( cage : PetCage ) : void { if( cage.content instanceof Pet ) return pushPet( cage ) } replacePet( new AnimalCage ) // allow replacePet( new PetCage ) // allow replacePet( new CatCage ) // allow replacePet( new DogCage ) // allow replacePet( new FoxCage ) // forbid

рдЗрд╕рдореЗрдВ рдЖрдк рдЬрд╛рдирд╡рд░ рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдлрд┐рд░ рд╡рд╣ рдЬрд╛рдВрдЪ рдХрд░реЗрдЧреА рдХрд┐ рдкрд┐рдВрдЬрд░реЗ рдореЗрдВ рдПрдХ рдкрд╛рд▓рддреВ рдЬрд╛рдирд╡рд░ рд╣реИ, рдЕрдиреНрдпрдерд╛ рд╡рд╣ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкрд╛рд▓рддреВ рдЬрд╛рдирд╡рд░ рдХреЗ рдЕрдВрджрд░ рд░рдЦ рджреЗрдЧреАред рдФрд░ рдЖрдк рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдмрд┐рд▓реНрд▓реА рдХреЗ рд╕рд╛рде рдПрдХ рдкрд┐рдВрдЬрд░реЗ, рдлрд┐рд░ рд╡рд╣ рд╕рд┐рд░реНрдл рдХреБрдЫ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг
рдХреБрдЫ рдХрд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рд╡рд┐рдЪрд░рдг рдХрд┐рд╕реА рддрд░рд╣ рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдЕрдХреНрд╕рд░ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рд╕рд░рдг рдХреЛ рдЕрдХреНрд╕рд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЗрдиреЗрд░рд┐рдХ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдордЭрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкреВрд░реА рдХрд╣рд╛рдиреА рдореЗрдВ рдЕрднреА рднреА рд╣рдорд╛рд░рд╛ рдПрдХ рднреА рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ - рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдареЛрд╕ рд╡рд░реНрдЧ рд╣реИ:
class AnimalCage { content : Animal } class PetCage extends AnimalCage { content : Pet } class CatCage extends PetCage { content : Cat } class DogCage extends PetCage { content : Dog } class FoxCage extends AnimalCage { content : Fox }
рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рд╡рд┐рдЪрд░рдг рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рд╕реЗ рдирд╣реАрдВ рдЬреБрдбрд╝реА рд╣реИрдВред рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдКрдкрд░ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
class Cage<Animal> { content : Animal }
рдФрд░ рдЕрдм рдЖрдк рдХрд┐рд╕реА рднреА рд╕реЗрд▓ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:
const animalCage = new Cage<Animal>() const petCage = new Cage<Pet>() const catCage = new Cage<Cat>() const dogCage = new Cage<Dog>() const foxCage = new Cage<Fox>()
рд╕реАрдорд╛рдУрдВ рдХреА рдШреЛрд╖рдгрд╛
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╕реВрдЪреАрдмрджреНрдз рд╕рднреА рдЪрд╛рд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдмрд┐рд▓реНрдХреБрд▓ рд╕рдорд╛рди рд╣реИрдВ:
( cage : PetCage )=> void
рдпрд╣реА рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕реНрд╡реАрдХреГрдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдРрд╕реЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдкреВрд░реНрдгрддрд╛ рдирд╣реАрдВ рд╣реИ - рдпрд╣ рдХрд╣рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЦреИрд░, рдЬрдм рддрдХ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд▓реЛрдордбрд╝реА рдХреЗ рд╕рд╛рде рдкрд┐рдВрдЬрд░реЗ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рдЖрдзреБрдирд┐рдХ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрди рд╣реИ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, C # рдореЗрдВ рдФрд░ рдмрд╛рд╣рд░ рд╕рдВрд╢реЛрдзрдХ:
interface ICageIn<in T> { T content { set; } } // contravariant generic parameter interface ICageOut<out T> { T content { get; } } // covariant generic parameter interface ICageInOut<T> { T content { get; set; } } // invariant generic parameter
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╕реА # рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рд╢реБрд░реВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ, рд╕реА # рдореЗрдВ рджреНрд╡рд┐рднрд╛рдЬрдХ рдЖрдорддреМрд░ рдкрд░ рдЕрдХреНрд╖рдореНрдп рд╣реИред
рдЖрдЙрдЯрдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░
рдХрд╛рд░реНрдп рди рдХреЗрд╡рд▓ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдорд╛рди рднреА рд▓реМрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдПрдХ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рдкрд╛рд▓рддреВ рдЬрд╛рдирд╡рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдкрд┐рдВрдЬрд░реЗ рд▓реЗрдиреЗ рдФрд░ рджреЛ рдкрд╛рд▓рддреВ рдЬрд╛рдирд╡рд░реЛрдВ рдХреЛ рд▓реМрдЯрд╛рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдХрд░реЗрдВред
function getPets( input : PetCage ) : [ Pet , Pet ] { return [ input.content , new Cat ] }
рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рджреЛ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рд╣реЛрддреЗ рд╣реИрдВред
function getPets( input : PetCage , output1 : PetCage , output2 : PetCage ) : void { output1.content = input.content output2.content = new Cat }
рдмрд╛рд╣рд░реА рдХреЛрдб рд╕реНрдЯреИрдХ рдкрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рд╡рд╣ рд╕рдм рдХреБрдЫ рдбрд╛рд▓рддрд╛ рд╣реИ рдЬреЛ рд╡рд╣ рдЙрд╕рдореЗрдВ рд╡рд╛рдкрд╕ рд▓реМрдЯрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рдФрд░ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░, рдХреЙрд▓рд┐рдВрдЧ рдХреЛрдб рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдкрдиреЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрди рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛ред

рдЗрди рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдорд╛рдирддрд╛ рд╕реЗ рдпрд╣ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдП рдЧрдП рдорд╛рди, рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╣рдореЗрд╢рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЖрдЙрдЯрдкреБрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реЛрддреЗ рд╣реИрдВред рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирд╕реЗ рдирд╣реАрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред
рдСрдмреНрдЬреЗрдХреНрдЯ рддрд░реАрдХреЗ
рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд┐рдзрд┐рдпрд╛рдБ рдПрдХ рдлрд╝рдВрдХреНрд╢рдирд▓ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреЙрдЗрдВрдЯрд░ рд▓реЗрдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВред рдЕрд░реНрдерд╛рддреН, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЛ рдХрд╛рд░реНрдп рд╕рдорддреБрд▓реНрдп рд╣реИрдВред
class PetCage { pushPet() : void { const Pet = random() > .5 ? Cat : Dog this.content = new Pet } }
function pushPet( this : PetCage ) : void { const Pet = random() > .5 ? Cat : Dog this.content = new Pet }
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдПрдХ рд╡рд┐рдзрд┐, рдПрдХ рдирд┐рдпрдорд┐рдд рдХрд╛рд░реНрдп рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рд╕рджрд╕реНрдп рднреА рд╣реИ, рдЬреЛ рдХрд┐ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реБрдкрд░рдЯрд╛рдЗрдк рдкреНрд░рддрд┐рдмрдВрдз рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ:
function fillPetCage( cage : PetCage ) { cage.pushPet() }

рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ pushPet
рдХреЛ рдкрд╛рд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ pushPet
рд╡рд┐рдзрд┐ pushPet
рдЕрднреА рддрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдЖрдХреНрд░рдордг рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд╕рдорд╛рди рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдиреАрдЪреЗ рдФрд░ рдКрдкрд░ рджреЛрдиреЛрдВ рд╕реЗ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, pushPet
рд╡рд┐рдзрд┐ рдХрд╛ рд╕реНрдерд╛рди рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рд╡рд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдУрд╡рд░рдЯрд╛рдЗрдк рд╕реАрдорд╛ рд╣реЛрдЧреАред
рдмрд╛рд░рдмрд░рд╛ рд▓рд┐рд╕реНрдХ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╕рд┐рджреНрдзрд╛рдВрдд (рдПрд▓рдПрд╕рдкреА)
рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рд╕реЛрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рдЙрдкрдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдкрд╛рдд рдкрд╣рд▓реЗ рд╕реЗ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдВрдХреАрд░реНрдгрддрд╛ рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рд╕реБрдкрд░рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдХрд┐рд╕реА рднреА рд╕реНрдерд╛рди рдкрд░ рдЙрдкрдкреНрд░рдХрд╛рд░ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╕реЗ рд╣реЛрддрд╛ рд╣реИред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХрд╛ рдХрд╛рд░рдг рдПрд▓рдПрд╕рдкреА рдореЗрдВ рдареАрдХ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдЗрдП рдЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ рдзреНрдпрд╛рди рд╕реЗ рдкрдврд╝реЗрдВ, рдЗрд╕ рдмрд╛рдд рдкрд░ рдзреНрдпрд╛рди рджреЗрдирд╛ рдХрд┐ рдкреНрд░рд╛рдердорд┐рдХ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдорд╛рдзреНрдпрдорд┐рдХ рдХреНрдпрд╛ рд╣реИ:
рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдп рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рдмрд┐рдирд╛ рдФрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рд╢реБрджреНрдзрддрд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд┐рдП рдмрд┐рдирд╛ рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп (рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдЬреЛ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рд╣реИрдВ) рд╕рд╣рд┐рдд, рдЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╕реЗ рдЙрдкрдкреНрд░рдХрд╛рд░ рдкреНрд░рддрд┐рдмрдВрдз рд▓реЗрдиреЗ рдХреА рдХреЛрдИ рдЬрдЧрд╣ рдирд╣реАрдВ рд╣реИред
рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд╕рд╛рде, рдпрд╣ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИ, рдЪреВрдВрдХрд┐ рдирд┐рдореНрди рджреЛ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдПрд▓рдПрд╕рдкреА рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ рдЕрдирдиреНрдп рд╣реИрдВ:
- рдХрдХреНрд╖рд╛
A
рдореЗрдВ B
рдЙрдкрд╡рд░реНрдЧ рд╣реИ, рдЬрд╣рд╛рдБ рдлрд╝реАрд▓реНрдб B::foo
, A::foo
рдХрд╛ рдЙрдк-рдкреНрд░рдХрд╛рд░ рд╣реИред - рдХреНрд▓рд╛рд╕
A
рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ A::foo
рдлреАрд▓реНрдб рдХреЛ рдмрджрд▓ рд╕рдХрддреА рд╣реИред
рддрджрдиреБрд╕рд╛рд░, рдХреЗрд╡рд▓ рддреАрди рддрд░реАрдХреЗ рдмрдЪреЗ рд╣реИрдВ:
- рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЙрдирдХреЗ рдХреНрд╖реЗрддреНрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдВрдХреБрдЪрд┐рдд рдХрд░рдиреЗ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдЖрдиреЗ рд╕реЗ рд░реЛрдХреЗрдВред рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЖрдк рдПрдХ рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП рдПрдХ рд╣рд╛рдереА рдХреЛ рдкрд┐рдВрдЬрд░реЗ рдореЗрдВ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
- рдПрд▓рдПрд╕рдкреА рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛ рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧред рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЖрдкрдХреЛ рдмрд╣реБрдд рд╕реЛрдЪрдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рд╕рдВрдХрд▓рдХ рдХреЛ рд╕рдордЭрд╛рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рддрд┐рдмрдВрдз рдХрд╣рд╛рдВ рд╣реИрдВред
- рд╕рдм рдХреБрдЫ рдкрд░ рдереВрдХрдирд╛ рдФрд░ рдЬрд╛рдирд╛
рдорда рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ, рдЬрд╣рд╛рдВ рд╕рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдирдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдШреЛрд╖рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╣рд╕рдВрдпреЛрдЬрдХ рд╣реИрдВред
рдЯрд╛рдЗрдкрдкреНрд░рддрд┐
рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рддрд░реНрдХ рд╕рд░рд▓ рд╣реИ: рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕рд╣рд╕рдВрдпреЛрдЬрдХ (рдЬреЛ рд╕рдЪ рдирд╣реАрдВ рд╣реИ) рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╡рд╛рдкрд╕реА рдорд╛рди рдХреЛ рдХрдВрдЯреНрд░рд╛рд╡реЗрд░рд┐рдПрдВрдЯ (рдЬреЛ рд╕рдЪ рд╣реИ) рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдкрд╣рд▓реЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рднрд┐рдиреНрдирддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЬреЛ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрд░рддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдШрдЯрдирд╛рдПрдВ рд╣реИрдВ:
abstract class Animal { is! : 'cat' | 'dog' | 'fox' } abstract class Pet extends Animal { is! : 'cat' | 'dog' } class Cat extends Pet { is! : 'cat' } class Dog extends Pet { is! : 'dog' } class Fox extends Animal { is! : 'fox' } class Cage<Animal> { content! : Animal } function pushPet( cage : Cage<Pet> ) : void { const Pet = Math.random() > .5 ? Cat : Dog cage.content = new Pet } pushPet( new Cage<Animal>() ) // forbid to push Pet to Animal Cage :-( pushPet( new Cage<Cat>() ) // allow to push Dog to Cat Cage :-(
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рдВрд╡реЗрджреА рдХреЛрдб рдХреЗ рдмрдЬрд╛рдп рд╕рдВрдХрд▓рдХ рдХреА рдорджрдж рдХрд░рдиреА рд╣реЛрдЧреА:
function pushPet< PetCage extends Cage<Animal> >( cage: Cage<Pet> extends PetCage ? PetCage : never ): void { const Pet = Math.random() > .5 ? Cat : Dog cage.content = new Pet } pushPet( new Cage<Animal>() ) // allow :-) pushPet( new Cage<Pet>() ) // allow :-) pushPet( new Cage<Cat>() ) // forbid :-) pushPet( new Cage<Dog>() ) // forbid :-) pushPet( new Cage<Fox>() ) // forbid :-)
рдСрдирд▓рд╛рдЗрди рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
FlowJS
FlowJS рдореЗрдВ рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдгрд╛рд▓реА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЯрд╛рдЗрдк рд╡рд┐рд╡рд░рдг рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ ред рд╣рдорд╛рд░реЗ рд╕реЗрд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
class Animal {} class Pet extends Animal {} class Cat extends Pet {} class Dog extends Pet {} class Fox extends Animal {} class Cage< Animal > { content : Animal } function touchPet( cage : { +content : Pet } ) : void { console.log( `touch ${typeof cage.content}` ) } function pushPet( cage: { -content: Pet } ): void { const Pet = Number((0: any)) > .5 ? Cat : Dog cage.content = new Pet } function replacePet( cage : { content : Pet } ) : void { touchPet( cage ) pushPet( cage ) } touchPet( new Cage<Animal> ) // forbid :-) touchPet( new Cage<Pet> ) // allow :-) touchPet( new Cage<Cat> ) // allow :-) touchPet( new Cage<Dog> ) // allow :-) touchPet( new Cage<Fox> ) // forbid :-) pushPet( new Cage<Animal> ) // allow :-) pushPet( new Cage<Pet> ) // allow :-) pushPet( new Cage<Cat> ) // forbid :-) pushPet( new Cage<Dog> ) // forbid :-) pushPet( new Cage<Fox> ) // forbid :-) replacePet( new Cage<Animal> ) // forbid :-) replacePet( new Cage<Pet> ) // allow :-) replacePet( new Cage<Cat> ) // forbid :-) replacePet( new Cage<Dog> ) // forbid :-) replacePet( new Cage<Fox>) // forbid :-)
рдСрдирд▓рд╛рдЗрди рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
рдпрд╣рд╛рдБ рдЕрд╡рд┐рднрд╛рдЬреНрдп рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдзрд┐рдХ рдЖрд╕рд╛рдиреА рд╕реЗ рд╡рд┐рдЪрд░рдг рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рдЗрд╕ рддрд░рд╣:
function pushPet( cage: Contra< Cage<Pet> , 'content' > ): void { const Pet = Number((0: any)) > .5 ? Cat : Dog cage.content = new Pet }
рд╕реА рддреЗрдЬ
рд╕реА # рдореВрд▓ рд░реВрдк рд╕реЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рднрд┐рдиреНрдирддрд╛ рдХреЗ рд╕рдордЭ рдХреЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдмрд╛рдж рдореЗрдВ рдЗрд╕рдореЗрдВ рдмрд╛рд╣рд░ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╕рдВрд╢реЛрдзрдХ рдЬреЛрдбрд╝ рджрд┐рдП рдЧрдП, рдЬрд┐рд╕рдиреЗ рд╕рдВрдХрд▓рдХ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЗрди рд╕рдВрд╢реЛрдзрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдлрд┐рд░ рд╕реЗ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИред
using System; abstract class Animal {} abstract class Pet : Animal {} class Cat : Pet {} class Dog : Pet {} class Fox : Animal {} interface ICageIn<in T> { T content { set; } } interface ICageOut<out T> { T content { get; } } interface ICageInOut<T> { T content { get; set; } } class Cage<T> : ICageIn<T>, ICageOut<T>, ICageInOut<T> { public T content { get; set; } } public class Program { static void touchPet( ICageOut<Pet> cage ) { Console.WriteLine( cage.content ); } static void pushPet( ICageIn<Pet> cage ) { cage.content = new Dog(); } static void replacePet( ICageInOut<Pet> cage ) { touchPet( cage as ICageOut<Pet> ); pushPet( cage as ICageIn<Pet> ); } void enshurePet( Cage<Pet> cage ) { if( cage.content is Pet ) return; pushPet( cage as ICageIn<Pet> ); } public static void Main() { var animalCage = new Cage<Animal>(); var petCage = new Cage<Pet>(); var catCage = new Cage<Cat>(); var dogCage = new Cage<Dog>(); var foxCage = new Cage<Fox>(); touchPet( animalCage ); // forbid :-) touchPet( petCage ); // allow :-) touchPet( catCage ); // allow :-) touchPet( dogCage ); // allow :-) touchPet( foxCage ); // forbid :-) pushPet( animalCage ); // allow :-) pushPet( petCage ); // allow :-) pushPet( catCage ); // forbid :-) pushPet( dogCage ); // forbid :-) pushPet( foxCage ); // forbid :-) replacePet( animalCage ); // forbid :-) replacePet( petCage ); // allow :-) replacePet( catCage ); // forbid :-) replacePet( dogCage ); // forbid :-) replacePet( foxCage ); // forbid :-) } }
рдСрдирд▓рд╛рдЗрди рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
рдЬрд╛рд╡рд╛
рдЬрд╛рд╡рд╛ рдореЗрдВ, рд╡рд┐рд╡рд┐рдзрддрд╛рдУрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛рдлреА рджреЗрд░ рд╕реЗ рдФрд░ рдХреЗрд╡рд▓ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝реА рдЧрдИ рдереА, рдЬреЛ рд╕реНрд╡рдпрдВ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рд╣рд╛рд▓ рд╣реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреАред рдпрджрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдкрд░реЗрд╢рд╛рдиреАред
abstract class Animal {} abstract class Pet extends Animal {} class Cat extends Pet {} class Dog extends Pet {} class Fox extends Animal {} class Cage<T> { public T content; } public class Main { static void touchPet( Cage<? extends Pet> cage ) { System.out.println( cage.content ); } static void pushPet( Cage<? super Pet> cage ) { cage.content = new Dog(); } static void replacePet(Cage<Pet> cage ) { touchPet( cage ); pushPet( cage ); } void enshurePet( Cage<Pet> cage ) { if( cage.content instanceof Pet ) return; pushPet( cage ); } public static void main(String[] args) { Cage<Animal> animalCage = new Cage<Animal>(); Cage<Pet> petCage = new Cage<Pet>(); Cage<Cat> catCage = new Cage<Cat>(); Cage<Dog> dogCage = new Cage<Dog>(); Cage<Fox> foxCage = new Cage<Fox>(); touchPet( animalCage );
рдСрдирд▓рд╛рдЗрди рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
рд╕реА ++
рд╕реА ++, рдЕрдкрдиреЗ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рд╡рд┐рдзрддрд╛рдПрдВ рд╡реНрдпрдХреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдмрд╣реБрдд рдХреЛрдб рд╣реИред
#include <iostream> #include <typeinfo> #include <type_traits> class Animal {}; class Pet: public Animal {}; class Cat: public Pet {}; class Dog: public Pet {}; class Fox: public Animal {}; template<class T> class Cage { public: T *content; }; template<class T, class = std::enable_if_t<std::is_base_of<Pet, T>::value>> void touchPet(const Cage<T> &cage) { std::cout << typeid(T).name(); } template<class T, class = std::enable_if_t<std::is_base_of<T, Pet>::value>> void pushPet(Cage<T> &cage) { cage.content = new Dog(); } void replacePet(Cage<Pet> &cage) { touchPet(cage); pushPet(cage); } int main(void) { Cage<Animal> animalCage {new Fox()}; Cage<Pet> petCage {new Cat()}; Cage<Cat> catCage {new Cat()}; Cage<Dog> dogCage {new Dog()}; Cage<Fox> foxCage {new Fox()}; touchPet( animalCage ); // forbid :-) touchPet( petCage ); // allow :-) touchPet( catCage ); // allow :-) touchPet( dogCage ); // allow :-) touchPet( foxCage ); // forbid :-) pushPet( animalCage ); // allow :-) pushPet( petCage ); // allow :-) pushPet( catCage ); // forbid :-) pushPet( dogCage ); // forbid :-) pushPet( foxCage ); // forbid :-) replacePet( animalCage ); // forbid :-) replacePet( petCage ); // allow :-) replacePet( catCage ); // forbid :-) replacePet( dogCage ); // forbid :-) replacePet( foxCage ); // forbid :-) return 0; }
рдСрдирд▓рд╛рдЗрди рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
рдбреА
D рдХреЗ рдкрд╛рд╕ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рдЪрд░рдг рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдИ рднреА рд╕рдВрддрд╛рди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЙрдирдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╣реИред
import std.stdio, std.random; abstract class Animal {} abstract class Pet : Animal { string name; } class Cat : Pet {} class Dog : Pet {} class Fox : Animal {} class Cage(T) { T content; } void touchPet( PetCage )( PetCage cage ) { writeln( cage.content.name ); } void pushPet( PetCage )( PetCage cage ) { cage.content = ( uniform(0,2) > 0 ) ? new Dog() : new Cat(); } void replacePet( PetCage )( PetCage cage ) { touchPet( cage ); pushPet( cage); } void main() { Cage!Animal animalCage; Cage!Pet petCage; Cage!Cat catCage; Cage!Dog dogCage; Cage!Fox foxCage; animalCage.touchPet();
рдСрдирд▓рд╛рдЗрди рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
рдЙрдкрд╕рдВрд╣рд╛рд░
рдЕрднреА рдХреЗ рд▓рд┐рдП рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдкреНрд░рд╕реНрддреБрдд рд╕рд╛рдордЧреНрд░реА рдиреЗ рдЖрдкрдХреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХреА рд╣реИ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХрд╣реАрдВ рдмреЗрд╣рддрд░, рдХрд╣реАрдВ рдмреБрд░рд╛, рдХрд╣реАрдВ рдХреЛрдИ рд░рд╛рд╕реНрддрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ - рддреЛ-рддреЛред рд╢рд╛рдпрдж рдпрд╣ рдЖрдк рд╣реА рд╣реИрдВ рдЬреЛ рдЙрд╕ рднрд╛рд╖рд╛ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░реЗрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╕рдм рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рдкреНрд░рдХрд╛рд░-рд╕реБрд░рдХреНрд╖рд┐рдд рджреЛрдиреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рдмреАрдЪ, рд╣рдорд╛рд░реА рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдЪреИрдЯ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ , рдЬрд╣рд╛рдВ рд╣рдо рдХрднреА-рдХрднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреА рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддреЗ рд╣реИрдВ ред