🔗 Tarefa
Imagine que você tenha várias sobrecargas de foo()
na sua linguagem favorita.
Você pode substituir todas essas sobrecargas por uma única função em Kotlin.
Altere a declaração da função foo
de forma que o código que usa foo
seja compilado.
Java
class SobrecargaJava { public String foo(String name, int number, boolean toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number; } public String foo(String name, int number) { return foo(name, number, false); } public String foo(String name, boolean toUpperCase) { return foo(name, 42, toUpperCase); } public String foo(String name) { return foo(name, 42); } }
C#
using System; class SobrecargaCSharp { public string Foo(string name, int number, bool toUpperCase) { return (toUpperCase ? name.ToUpper() : name) + number; } public string Foo(string name, int number) { return Foo(name, number, false); } public string Foo(string name, bool toUpperCase) { return Foo(name, 42, toUpperCase); } public string Foo(string name) { return Foo(name, 42); } }
Dart
class SobrecargaDart { String foo(String name, int number, bool toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number.toString(); } String foo(String name, int number) { return foo(name, number, false); } String foo(String name, bool toUpperCase) { return foo(name, 42, toUpperCase); } String foo(String name) { return foo(name, 42); } }
Go
package main import ( "fmt" "strings" ) type SobrecargaGo struct{} func (s SobrecargaGo) Foo(name string, number int, toUpperCase bool) string { if toUpperCase { return strings.ToUpper(name) + fmt.Sprintf("%d", number) } return name + fmt.Sprintf("%d", number) } func (s SobrecargaGo) FooWithNumber(name string, number int) string { return s.Foo(name, number, false) } func (s SobrecargaGo) FooWithUpperCase(name string, toUpperCase bool) string { return s.Foo(name, 42, toUpperCase) } func (s SobrecargaGo) FooWithName(name string) string { return s.Foo(name, 42, false) }
JavaScript
class SobrecargaJavaScript { foo(name, number, toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number; } fooWithNameAndNumber(name, number) { return this.foo(name, number, false); } fooWithNameAndUpperCase(name, toUpperCase) { return this.foo(name, 42, toUpperCase); } fooWithName(name) { return this.foo(name, 42); } }
PHP
foo($name, $number, false); } public function fooWithUpperCase($name, $toUpperCase) { return $this->foo($name, 42, $toUpperCase); } public function fooWithName($name) { return $this->foo($name, 42, false); } }
Python
class SobrecargaPython: def foo(self, name, number, to_upper_case): return (name.upper() if to_upper_case else name) + str(number) def foo_with_number(self, name, number): return self.foo(name, number, False) def foo_with_upper_case(self, name, to_upper_case): return self.foo(name, 42, to_upper_case) def foo_with_name(self, name): return self.foo(name, 42, False)
Swift
class SobrecargaSwift { func foo(name: String, number: Int, toUpperCase: Bool) -> String { return (toUpperCase ? name.uppercased() : name) + String(number) } func foo(name: String, number: Int) -> String { return foo(name: name, number: number, toUpperCase: false) } func foo(name: String, toUpperCase: Bool) -> String { return foo(name: name, number: 42, toUpperCase: toUpperCase) } func foo(name: String) -> String { return foo(name: name, number: 42) } }
TypeScript
class SobrecargaTypeScript { foo(name: string, number: number, toUpperCase: boolean): string { return (toUpperCase ? name.toUpperCase() : name) + number.toString(); } fooWithNumber(name: string, number: number): string { return this.foo(name, number, false); } fooWithUpperCase(name: string, toUpperCase: boolean): string { return this.foo(name, 42, toUpperCase); } fooWithName(name: string): string { return this.foo(name, 42); } }
Caso de uso
Quando se fala em [default arguments
(https://kotlinlang.org/docs/functions.html#default-arguments) ou argumentos padrão, está se referindo a uma caracterÃstica bem prática em Kotlin.
Ela permite que alguns argumentos sejam deixados de lado quando alguém chama uma função.
Se isso acontecer, o compilador usa esses argumentos padrão no lugar dos argumentos que foram pulados.
fun calculaDesconto(preco: Double, taxaDesconto: Double = 0.05) = preco - preco * taxaDesconto calculaDesconto(preco = 50.0) calculaDesconto(preco = 100.0, taxaDesconto = 0.10)
No exemplo acima, o parâmetro taxaDesconto
tem um valor padrão de 5% de desconto. Ao chamar a função calculaDesconto
sem especificar a taxaDesconto
, o desconto de 5% será aplicado sobre o preço.
Porém, ao passar 0.10
como argumento para o parâmetro taxaDesconto
, esse será o valor utilizado, substituindo o desconto padrão de 5% para 10%.
Parâmetro x Argumento
A diferença entre parâmetro e argumento em Kotlin pode ser compreendida da seguinte forma:
- Parâmetro: identificado dentro da definição de uma função.
- Argumento: identificado ao invocar ou usar essa função, ou seja, fora da definição.
Imagine uma função que simula a preparação de um café:
fun prepararCafe(tipo: String) = "Preparando um café $tipo..."
Nesta definição, tipo
é considerado um parâmetro da função.
Ao solicitar a preparação de um café:
val pedido = prepararCafe("espresso")
Neste contexto, "espresso" é um argumento passado para a função prepararCafe()
.
Vantagens
- Menos sobrecargas: permite uma única função em vez de várias versões com diferentes argumentos.
- Flexibilidade: é possÃvel chamar a função com diferentes combinações de parâmetros, contanto que os argumentos obrigatórios sejam fornecidos.
- Compatibilidade com Java: funções com argumentos padrão são compatÃveis com código Java, atuando como sobrecargas.
Desvantagens
- Complexidade do código: se usados em excesso, podem complicar a leitura e o entendimento do código.
- Descarte no bytecode Java: No Java, argumentos padrão do Kotlin não são reconhecidos. Para contornar isso, é necessário usar a anotação
@JvmOverloads
Top comments (0)