首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java 中到底是应该用接口类型 还是实现类的类类型去引用对象?

如题,Java 中到底是应该用接口类型 还是实现类的类类型去引用对象?首先贴出答案: 应该优先使用接口而不是类来引用对象,但只有存在适当的接口类型时 。...ClassB();//类类型的引用变量A 去接收对象地址 什么时候接口类型不适合做引用呢,我们看下面这个例子: interface A { //接口A //接口的方法声明必须是...: A temp=new B(); 用接口类型的引用变量temp,去接收实现类B实例化出来的对象地址(这里的=是传递的地址)。...(当然A demo=new A();是不可能的,因为接口是不能用来实例化对象的,但可以用来声明一个接口类型的引用变量)。...(当然A demo=new A();是不可能的,因为接口是不能用来实例化对象的,但可以用来声明一个接口类型的引用变量)。

1.6K30

C++核心准则C.148:使用dynamic_cast进行指针类型转换时,将不能发现目标类看作是有效的选项

type when failure to find the required class is considered a valid alternative C.148:使用dynamic_cast进行指针类型转换时...,将不能发现目标类看作是有效的选项 Reason(原因) The dynamic_cast conversion allows to test whether a pointer is pointing...和C.147不同,那里的失败是错误,而且不应该被用于条件执行。...下面的例子描述的是Shape_owner的增加函数,它接受构造出来的Shape对象的所有权。对象也会在根据它们的几何属性有序加入views容器。在这个例子中,图形没有从几何属性继承。...寻找所需类的失败会导致dynamic_cast返回一个空值,而解引用一个空指针会引起无定义的行为。因此应该总是认为dynamic_cast的结果可能为空并进行检查。

95010
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Java运行时多态性:继承和接口的实现

    java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。...另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。...不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,否则子类必须被abstract修饰符修饰,当然也就不能被实例化了。...我们可以定义一个接口类型的引用变量来引用实现接口的类的实例,当这个引用调用方法时,它会根据实际引用的类的实例来判断具体调用哪个方法,这和上述的超类对象引用访问子类对象的机制相似。...需要注意的一点是:Java在利用接口变量调用其实现类的对象的方法时,该方法必须已经在接口中被声明,而且在接口的实现类中该实现方法的类型和参数必须与接口中所定义的精确匹配。

    1.8K50

    Java常量池解析与字符串intern简介

    对目标类型的超类 的加载必然是在对当前类型加载完的基础上进行的,因为只有加载完当前类型,才能从class文件的super_class域找到其直接超类的符号引用,再 递归进行解析和加载,直至java.lang.Object...而在递归返回的过程中,会检查interfaces域以查看实现或扩展了哪些接口,并再次 递归遍历对接口的符号引用。 (2).检查访问权限 随后是对目标类型的连接和初始化,这样才可以正常使用该类型。...类型的连接和初始化步骤如下: (3).类型校验 (4).类型准备 (5).类型解析(可推迟) 注意该过程是对被引用类型及其超类的符号引用的解析,因为对于被引用类型的某些符号引用不会立刻用到,故该步骤之前是严格意义上属于发起引用的类型的符号...但对于重写的方法将出现在超类对应的位置(该方法第一次出现的位置)。 但是访问接口方法就不能简单地通过方法表的偏移量来进行访问,而必须搜索对象的类的方法表来找到该方法。...比如Factory接口分别由A和B来实现其produce()方法,但由于A和B不能保证由同一个实现了Factory接口的超类派生,即有着同样的produce()方法偏移,那么就无法通过方法表的偏移来访问

    52820

    Java抽象类与oop三大特征

    接口是抽象类的延伸,java为了了保证数据安全是不能多重继承的,也就是说 继承只能存在一个父类 ,但是接口不同, 一个类可以同时实现多个接口 ,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多重继承的缺陷...7、 如果实现类要访问接口中的成员,不能使用 super 关键字。因为两者之间没有显示的继承关系,况且接口中的成员成员属性是静态的 8、接口没有构造方法。...public static final类型的; 3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法; 4)一个类只能继承一个抽象类,而一个类却可以实现多个接口, Java是单继承..., 被引用对象的类型 而不是引用变量的类型决定了调用谁的成员方法, 但是这个被调用的方法必须是在超类中定义过的 ,也就是说被调用的方法必须是 被子类重写的方法 。...((super)O),this仍然是b,这里O为C,由于B是C的超类,因此它到类B里面找show(B obj)的方法,因此输出为”B and B”。

    80540

    Scala专题系列(六) : Scala特质

    Scala和Java一样不允许类从多个超类继承,在Java中类只能扩展 自一个超类,它可以实现多个接口,但接口中只能包含抽象方法,不能包含字段 Scala提供的"特质"类似于java中的接口, 但又有所不同...另外特质中不能有构造器参数,每个特质都有一个无参数的构造器 特质没有构造器参数是特质与类之间的其中一个差别,其它的特质具备类的所有特性,比如具体的和抽象的字段,以及超类 特质扩展类 上面我们看到了特质可以扩展另一个特质...with LoggerException 上面代码是可以的,因为UnHappyException继承了IOException,而IOException是扩展自Exception 自身类型: 当特质扩展类时...,编译器能够确保所有混入该特质的类都认这个类为超类,Scala还有另一套机制可以保证这一点:自身类型(self type) 当特质以如下代码开始定义时: this:类型 => 它便能够被混入指定类型的子类...类型,而下面代码 val h = new Home with LoggerException 上面代码是不合法的,因为Home不是Exception的子类型 同时,特质还可以处理结构类型,这种类型只给出类必须拥有的方法

    70020

    《流畅的Python》第十二章学习笔记

    子类化内置类型 在Python2.2之前,内置类型不能子类化 内置类型不会掉用用户定义的类覆盖的特殊方法。...这个顺序叫方法解析顺序「Method Resolution Order,MRO」 类都有一个名为__mro__的属性,它的值是一个元祖,按照方法解析顺序列出各个超类,从当前类一直向上,直到object类...) ⚠️直接在类上调用实例方法,必须显式传入self参数,因为这样访问的是未绑定方法 处理多重继承的建议 把接口继承和实现继承区分开 创建子类的原因: 继承接口,创建子类型,实现「是什么」关系 继承实现...,通过重用避免代码重复 接口继承是框架的支柱。...继承重用代码是实现细节,通常可以换用组合和委托模式 使用抽象基类显式表示接口 创建abc.ABC或其他抽象基类的子类 通过混入重用代码 混入类绝对不能实例化,而且具体类不能只继承混入类。

    44010

    重构-改善既有代码的设计:处理概括关系 (九)

    这里不能运用 Pull Up Method (方法上移),因为你无法在子类中继承超类构造函数。...有时候这种行为上的差异是通过类型码区分的,此时你可以使用Replace Type Code with Subclass (以子类取代类型码)或Replace Type Code with State/Strategy...Extract Subclass (提炼子类)和Extract Interface (提炼接口)之间有些相似之处。Extract Interface (提炼接口)只能提炼共通接口,不能提炼共通代码。...你可以针对每个角色以Extract Interface (提炼接口)提炼出相应接口。另一种可以用Extract Interface (提炼接口)的情况是:你想要描述一个类的外部依赖接口。...另一种需要当心的情况是:受托对象被不止一个其他对象共享,而且受托对象是可变的。在这种情况下,你就不能将委托关系替换为继承关系,因为这样就无法再共享数据了。

    49010

    Java基础:继承

    这是因为 Manager 类的 getSalary 方法不能直接地访问超类的私有域。...,二是调用超类的构造器。...导出类中接口扩展部分不能被基类访问,因此,一旦向上转型,就不能调用那些新方法。 5. 继承的特性 Java 语言的继承是单继承,不允许一个类继承多个父类。...向上转型是从一个较专用类型向较通用类型转换。 导出类是基类的一个超集。它可能比基类含有更多的方法,但它必须至少具备基类中所有的方法。 6....组合与继承 继承和组合都能从现有类型生成新类型,组合一般是将现有类型作为新类型的底层实现的一部分加以复用,而继承复用的是接口。 组合在开发过程中常使用的手段,显示的在新类中放置子对象。

    57910

    Scala特质

    特质:trait是Scala里代码复用的基础单元。特质封装了方法和字段的定义,并可以通过混入到类中重用它们。不像类的继承那样,每个类都只能继承唯一的超类,类可以混入任意个特质。...它们最常用到的两种方式:拓宽瘦接口为胖接口和定义可堆叠的改变。 ? 这个特质名为Philosophical。它没有声明超类,因此和类一样,有个缺省的超类AnyRef。...下列这种情况下隐式地继承了特质的超类,从特质继承的方法可以像从超类继承的方法那样使用。 ? 特质同样也是类型:phil的类型是Philosophical,一个特质。...因此,变量phil可以被初始化为任何混入了Philosophical特质的类的对象。 ? 特质就像是带有具体方法的Java接口,不过其实它能做的更多。特质可以,比方说,声明字段和维持状态值。...实际上,你可以用特质定义做任何用类定义做的事,并且语法也是一样的,除了两点。第一点,特质不能有任何“类”参数,也就是说,传递给类的主构造器的参数。 ?

    48430

    0001_Java泛型

    泛型接口的声明方式同泛型类是一致的,在接口名后紧跟一个尖括号,里面放置类型参数 interface Comparable { public int compareTo( AnyType...>接口,且该接口里的类型必须是泛型类型及其超类 public static 类型参数,那么使用的是原始类 由于类型擦除的存在,有以下的限制需要遵守: 基本类型 - 基本类型不能用做类型参数,如GenericMemoryCell就是错误的,必须使用基本类型的包装类...由于实际上只存在一个原始类,因此static域在该类的诸泛型实例之间是共享的 泛型类型的实例化 不能创建泛型类型的实例,注意是泛型类型的实例,而不是泛型类的实例。...T obj = new T(); 中右边的实例化是非法的 泛型数组对象 也不能创建一个泛型类型的数组,注意是泛型类型的数组,而不是泛型类的数组 T[] arr = new T[10];中右边的数组实例化是非法的

    31000

    Java基础系列(三十七):泛型继承,通配符,泛型反射

    extends Fruit); 这样就会看的很明显,因为如果我们去调用 setFirst()方法,编译器之可以知道是某个 Fruit的子类型,而不能确定具体是什么类型,它拒绝传递任何特定的类型,因为 ?...带有超类型限定的通配符的行为与子类型限定的通配符行为完全相反,可以为方法提供参数,但是却不能获取具体的值,即访问器是不安全的,而更改器方法是安全的: ?...> p) 通配符不是类型变量,所以,我们在编写代码的时候不能使用 "?"作为一种类型,也就是说,下面的代码是错误的: ?...通配符捕获只有在有许多限制的情况下才是合法的。编译器必须能够确信通配符表达的是单个,确定的类型。例如, ArrayList>中的 T永远不能捕获 ArrayList) WildcardType接口,描述通配符 ParameterizedType接口,描述泛型类或接口类型 GenericArrayType接口,描述泛型接口 下面是一个使用泛型反射API

    64330

    【C++】异常处理 ④ ( 异常接口声明 | 异常接口语法 | 抛出一种类型的异常 | 抛出多种类型的异常 | 抛出任意类型的异常 | 不能抛出异常 | 抛出异常类型错误 | 代码示例 )

    的 自定义异常类 来表示 异常 ; " 异常接口 " 用于表示 在 函数中 要抛出的 异常类型 ; 为了 加强 程序的 可读性 , 可维护性 , 推荐将 函数 可能会抛出异常 写入到 函数的 异常接口...中,即 在 函数中国年 列出所有可能抛出的异常类型 ; 2、异常接口语法 在 C++ 语言中 , 异常接口 的声明使用 throw() 关键字 , 用于指定函数要抛出的异常类型 ; 异常接口语法如下.../ 声明 throw(…) 可抛出任何类型异常 的 函数 , 有如下两种声明方式 : 不声明异常接口 : 在 函数 中 , 如果 不声明 异常接口 , 默认可以抛出任何类型的异常 ; // 1....throw(…) 异常接口 : 如果 函数的 异常接口 声明为 throw(…) , 则可以抛出任意类型的异常 ; // 在 函数 中 抛出任意类型异常 void fun() throw(...) {...cout 类型 异常 " << endl; // 抛出一个 char 类型的异常 throw 'A'; } 6、不能抛出任何类型异常 - 声明 throw() 如果禁止函数抛出异常

    60210

    Golang 函数返回类型是接口时返回对象的指针还是值

    1.接口简介 Interface 是一组抽象方法(未具体实现的方法,仅包含方法名参数返回值的方法)的集合,如果实现了 interface 中的所有方法,即该类型就实现了该接口。...注意: (1)接口中不能含有属性; (2)每种类型都能实现多个接口; (3)未初始化的接口类型变量的值为 nil。...接口声明格式: type InterfaceName interface { //方法列表 } 2.函数返回类型是接口时返回对象的指针还是值 函数返回类型是接口时返回对象的指针还是值,这个要看具体的需要...createEmployeeObj() o.Set() o.Print() e.Print() } 输出结果: company=alibaba company=alibaba 可见函数返回类型是接口时返回对象的指针...company="alibaba" e1.Print() } e.Print() } 输出结果: company=alibaba company=tencent 可见函数返回类型是接口时返回对象的值

    8.1K30

    5.1 类、超类和子类

    类的getSalary方法不能直接地访问超类的私有域。...但是Java支持“声明多继承”——Java的接口的多继承——一个类可以实现多个接口(“继承”了多个接口上的方法声明),而一个接口可以继承多个接口(同样是“继承”了多个接口上的方法声明)。...可以将一个子类变量赋给一个超类变量,但不能将一个超类变量赋给一个子类变量。 5.1.3 动态绑定   调用方法的过程可以分解为:   (1)编译器查看对象的声明类型和方法名。...假设x的实际类型是D,它是C类的子类,如果D类定义了一个方法f(String),就直接调用它,否则就在D类的超类中寻找f(String)方法,以此类推。   ...一个子类的引用赋给一个超类变量,编译器是允许的,但是将一个超类变量的引用赋给一个子类变量,必须进行类型转换,这样才能够通过运行时的检查。

    1.1K90
    领券