我有一个集合(或列表或数组列表),我想在其中放置String值和double值.我决定使它成为一个对象集合并使用重载ond多态,但我做错了.
我做了一点测试:
public class OOP {
void prova(Object o){
System.out.println("object");
}
void prova(Integer i){
System.out.println("integer");
}
void prova(String s){
System.out.println("string");
}
void test(){
Object o = new String(" ");
this.prova(o); // Prints 'object'!!! Why?!?!?
}
public static void main(String[] args) {
OOP oop = new OOP();
oop.test(); // Prints 'object'!!! Why?!?!?
}
}
Run Code Online (Sandbox Code Playgroud)
在测试中,似乎参数类型是在编译时而不是在运行时决定的.这是为什么?
这个问题与以下内容有关:
编辑:
好的,要调用的方法是在编译时决定的.是否有解决方法以避免使用instanceof运营商?
我所说的是无法定义:
data A = A {name :: String}
data B = B {name :: String}
Run Code Online (Sandbox Code Playgroud)
我知道GHC只是将其解释为普通函数,解决这个问题的惯用方法是:
data A = A {aName :: String}
data B = B {bName :: String}
class Name a where
name :: a -> String
instance Name A where
name = aName
instance Name B where
name = bName
Run Code Online (Sandbox Code Playgroud)
写完这篇文章之后,我不太喜欢它......难道这个类型化不能成为荒谬过程的一部分吗?
当我写一些Aeson JSON解析时,我想到了这个想法.如果只是为每种数据类型派生FromJSON实例都太容易了,我必须手工编写所有内容(目前> 1k行和计数).拥有像name或简单地value在数据记录中的名称并不常见.
http://www.haskell.org/haskellwiki/Performance/Overloading提到函数重载会引入一些运行时开销.但实际上我不明白为什么编译器无法在编译时解析它并在内部给它们不同的名称.
这个来自2012年的SO问题或多或少地说明了历史原因并指出了2006年的邮件主题.最近有什么变化吗?
即使存在一些运行时开销,大多数人也不会介意,因为大多数代码几乎不是性能关键.
是否有一些隐藏的语言扩展实际允许这个?我不确定......但我认为伊德里斯实际上是这样做的?
在C++ 14中,什么是一种理解函数或函数对象的好方法?
特别是,我有一个foo带有一些随机数量的重载的重载函数:可以通过ADL找到一些重载,其他的可以在无数个地方定义.
我有一个帮助对象:
static struct {
template<class...Args>
auto operator()(Args&&...args)const
-> decltype(foo(std::forward<Args>(args)...))
{ return (foo(std::forward<Args>(args)...));}
} call_foo;
Run Code Online (Sandbox Code Playgroud)
这让我可以将重载集作为单个对象传递.
如果我想要咖喱foo,我该怎么办呢?
由于curry和部分功能应用程序经常互换使用,curry我的意思是,如果foo(a,b,c,d)是有效的呼叫,那么curry(call_foo)(a)(b)(c)(d)必须是有效的呼叫.
由于C#添加了可选参数,因此使用可选参数或方法重载被认为是更好的做法,或者是否存在您希望使用其中一个的特定情况.即具有许多参数的函数更适合w /可选参数?
我知道覆盖和重载之间的语法差异.而且我也知道overriding是运行时多态,而重载是编译时多态.但我的问题是:"重载是真的编译时多态吗?方法调用是否真的在编译时解决?".为了澄清我的观点,让我们考虑一个示例类.
public class Greeter {
public void greetMe() {
System.out.println("Hello");
}
public void greetMe(String name) {
System.out.println("Hello " + name);
}
public void wishLuck() {
System.out.println("Good Luck");
}
}
Run Code Online (Sandbox Code Playgroud)
由于所有方法greetMe(), greetMe(String name), wishLuck()都是公开的,所以它们都可以被覆盖(包括重载的方法),对吧?例如,
public class FancyGreeter extends Greeter {
public void greetMe() {
System.out.println("***********");
System.out.println("* Hello *");
System.out.println("***********");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,请考虑以下代码段:
Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();
Run Code Online (Sandbox Code Playgroud)
该getRandomGreeter()方法返回一个随机Greeter对象.它可以返回其对象Greeter或其任何子类,如FancyGreeter或GraphicalGreeter或任何其他子类.在getRandomGreeter()将或者使用创建的对象new或动态地加载类文件,并使用反射(我认为这是可能的反射)或这是可能的任何其他方式创建对象.所有这些方法都Greeter可以在子类中重写或不重写.因此编译器无法知道是否覆盖了特定方法(是否重载).对?此外,维基百科在虚拟功能上说:
在Java中,所有非静态方法默认为"虚函数".只有标记为关键字final的方法(不能被覆盖)以及未被继承的私有方法才是非虚拟方法.
因为,使用动态方法分派在运行时解析虚函数,并且由于所有非私有,非最终方法都是虚拟的(无论是否过载),因此必须在运行时解析它们.对?
那么,如何在编译时仍然可以解决重载?或者,有什么我误解了,或者我错过了什么?
我在我的Javascript代码中使用如下方法重载.
function somefunction()
{
//1st function
}
function somefunction(a)
{
//2nd function
}
function somefunction(a,b)
{
//3rd function
}
somefunction(); // function call goes here
Run Code Online (Sandbox Code Playgroud)
我不明白的是,如果我调用somefunction()javascript应该调用第一个函数,但问题是javascript实际上调用第三个函数.这是为什么?如何调用第1和第2功能?这是什么原因?有没有一种在Javascript中实现方法重载的正确方法?什么是行业标准?
C++ 11使得基于引用限定符重载成员函数成为可能:
class Foo {
public:
void f() &; // for when *this is an lvalue
void f() &&; // for when *this is an rvalue
};
Foo obj;
obj.f(); // calls lvalue overload
std::move(obj).f(); // calls rvalue overload
Run Code Online (Sandbox Code Playgroud)
我理解这是如何工作的,但它的用例是什么?
我看到N2819建议将标准库中的大多数赋值运算符限制为左值目标(即向赋值运算符添加" &"引用限定符),但这被拒绝了.所以这是一个潜在的用例,委员会决定不再使用它.那么,再一次,什么是合理的用例?
我有一些代码
#define DEBUG_PRINT(x,...) \
do \
{\
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wunused-value\"") \
__typeof__((0,x)) _x = x; \
_Pragma("GCC diagnostic pop") \
DEBUG_PRINT_PTR((#x), &_x, __VA_ARGS__);\
} while(0)
//The repetition of debug_print_printf_specifier is to avoid repetition for custom types.
#define DEBUG_PRINT_PTR(xstr, xp,...) \
_Generic((*xp), \
const char *: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\
char *: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\
int: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\
float: debug_print_printf_specifier(xstr, …Run Code Online (Sandbox Code Playgroud) 以下是Java 7中的代码编译,但不是openjdk-1.8.0.45-31.b13.fc21.
static void f(Object o1, int i) {}
static void f(Object o1, Object o2) {}
static void test(boolean b) {
String s = "string";
double d = 1.0;
// The supremum of types 'String' and 'double' is 'Object'
Object o = b ? s : d;
Double boxedDouble = d;
int i = 1;
f(o, i); // fine
f(b ? s : boxedDouble, i); // fine
f(b ? s : d, i); // ERROR! Ambiguous
}
Run Code Online (Sandbox Code Playgroud)
编译器声称最后一个方法调用不明确.
如果我们改变的第二个参数的类型f …
我有以下课程:
public class BaseRepository
{
public virtual void Delete(int id)
{
Console.WriteLine("Delete by id in BaseRepository");
}
}
public class EFRepository: BaseRepository
{
public override void Delete(int id)
{
Console.WriteLine("Delete by Id in EFRepository");
}
public void Delete(object entity)
{
Console.WriteLine("Delete by entity in EFRepository");
}
}
Run Code Online (Sandbox Code Playgroud)
然后我用它像:
var repository = new EFRepository();
int id = 1;
repository.Delete(id);
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下只会EFRepository.Delete(object entity)打电话?
overloading ×10
java ×3
c# ×2
c++ ×2
polymorphism ×2
aeson ×1
c ×1
c++11 ×1
c++14 ×1
coding-style ×1
currying ×1
haskell ×1
idris ×1
inheritance ×1
java-8 ×1
javascript ×1
jquery ×1
oop ×1
overriding ×1
qualifiers ×1
record ×1
templates ×1
typeof ×1