java·中··!什么是类、对象和接口?

java·中··!什么是类、对象和接口?,第1张

我们把具有相同特性的事物划分成类:比如天上飞的动物我们叫他“飞禽”或者“鸟”类,水里游的叫“鱼”,用这个方法将他们分类,对象是类的具体话,比如说,类中的“人”,将人具体成对象,比如说“凤姐”、“芙蓉姐”,当然也有人把他们分到其他类里,接口可以简单理解,比如说电脑里有文件,那么桌面的“快捷方式”就是接口,我们通过这个接口可以找到指定的文件或程序。如果文件的内容变了,只要名称不变,这个快捷方式都能找到你要的文件。

从技术上讲 接口是一组包含了函数型方法的数据结构 通过这组数据结构 客户代码可以调用组件对象的功能

定义接口成员接口可以包含一个和多个成员 这些成员可以是方法 属性 索引指示器和事件 但不能是常量 域 *** 作符 构造函数或析构函数 而且不能包含任何静态成员 接口定义创建新的定义空间 并且接口定义直接包含的接口成员定义将新成员引入该定义空间 说明

· 接口的成员是从基接口继承的成员和由接口本身定义的成员

· 接口定义可以定义零个或多个成员 接口的成员必须是方法 属性 事件或索引器 接口不能包含常数 字段 运算符 实例构造函数 析构函数或类型 也不能包含任何种类的静态成员

· 定义一个接口 该接口对于每种可能种类的成员都包含一个 方法 属性 事件和索引器

· 接口成员默认访问方式是public 接口成员定义不能包含任何修饰符 比如成员定义前不能加abstract public protected internal private virtual override 或static 修饰符

· 接口的成员之间不能相互同名 继承而来的成员不用再定义 但接口可以定义与继承而来的成员同名的成员 这时我们说接口成员覆盖了继承而来的成员 这不会导致错误 但编译器会给出一个警告 关闭警告提示的方式是在成员定义前加上一个new关键字 但如果没有覆盖父接口中的成员 使用new关键字会导致编译器发出警告

· 方法的名称必须与同一接口中定义的所有属性和事件的名称不同 此外 方法的签名必须与同一接口中定义的所有其他方法的签名不同

· 属性或事件的名称必须与同一接口中定义的所有其他成员的名称不同

· 一个索引器的签名必须区别于在同一接口中定义的其他所有索引器的签名

· 接口方法声明中的属性(attributes) 返回类型(return type) 标识符(identifier)和形式参数列表(formal parameter lis)与一个类的方法声明中的那些有相同的意义 一个接口方法声明不允许指定一个方法主体 而声明通常用一个分号结束

· 接口属性声明的访问符与类属性声明的访问符相对应 除了访问符主体通常必须用分号 因此 无论属性是读写 只读或只写 访问符都完全确定

· 接口索引声明中的属性(attributes) 类型(type)和形式参数列表(formal parameter list)与类的索引声明的那些有相同的意义

下面例子中接口IMyTest包含了索引指示器 事件E 方法F 属性P这些成员

interface IMyTest{    string this[int index] { get; set; }    event EventHandler E ;    void F(int value)  ;    string P { get; set; }}public delegate void EventHandler(object sender EventArgs e) ;

下面例子中接口IStringList包含每个可能类型成员的接口 一个方法 一个属性 一个事件和一个索引

public delegate void StringListEvent(IStringList sender);public interface IStringList{ void Add(string s); int Count { get; } event StringListEvent Changed; string this[int index] { get; set; }}

接口成员的全权名使用接口成员也可采用全权名(fully qualified name) 接口的全权名称是这样构成的 接口名加小圆点 再跟成员名比如对于下面两个接口

interface IControl {    void Paint( ) ;}interface ITextBox: IControl {    void GetText(string text) ;}

其中Paint 的全权名是IControl Paint GetText的全权名是ITextBox GetText 当然 全权名中的成员名称必须是在接口中已经定义过的 比如使用ITextBox Paint 就是不合理的

如果接口是名字空间的成员 全权名还必须包含名字空间的名称

namespace System{    public interface IDataTable {        object Clone( ) ;    }}

那么Clone方法的全权名是System IDataTable Clone

定义好了接口 接下来我们关心的就是怎样实现对接口的访问 这部分内容 我将在下一篇文章中和您进一步探讨

定义接口的一般形式为 [attributes] [modifiers] interface identifier [:base list] {interface body}[;]

说明

· attributes(可选) 附加的定义性信息

· modifiers(可选) 允许使用的修饰符有new和四个访问修饰符 分别是 new public protected internal private 在一个接口定义中同一修饰符不允许出现多次 new修饰符只能出现在嵌套接口中

表示覆盖了继承而来的同名成员 The public protected internal and private修饰符定义了对接口的访问权限

· 指示器和事件

· identifier 接口名称

· base list(可选):包含一个或多个显式基接口的列表 接口间由逗号分隔

· interface body 对接口成员的定义

· 接口可以是命名空间或类的成员 并且可以包含下列成员的签名 方法 属性 索引器

· 一个接口可从一个或多个基接口继承

接口这个概念在C#和Java中非常相似 接口的关键词是interface 一个接口可以扩展一个或者多个其他接口 按照惯例 接口的名字以大写字母 I 开头 下面的代码是C#接口的一个例子 它与Java中的接口完全一样

interface IShape  {     void Draw ( ) ;}

如果你从两个或者两个以上的接口派生 父接口的名字列表用逗号分隔 如下面的代码所示

interface INewInterface: IParent IParent { }

然而 与Java不同 C#中的接口不能包含域(Field) 另外还要注意 在C#中 接口内的所有方法默认都是公用方法 在Java中 方法定义可以带有public修饰符(即使这并非必要) 但在C#中 显式为接口的方法指定public修饰符是非法的 例如 下面的C#接口将产生一个编译错误

interface IShape { public void Draw( ) ; }

下面的例子定义了一个名为IControl 的接口 接口中包含一个成员方法Paint

interface IControl {void Paint( ) ;}

在下例中 接口 IInterface从两个基接口 IBase 和 IBase 继承

interface IInterface: IBase IBase {   void Method ( ) ;   void Method ( ) ;}

接口可由类实现 实现的接口的标识符出现在类的基列表中 例如

class Class : Iface Iface {   // class 成员 }

类的基列表同时包含基类和接口时 列表中首先出现的是基类 例如

class ClassA: BaseClass Iface Iface {   // class成员 }

以下的代码段定义接口IFace 它只有一个方法

interface IFace {  void ShowMyFace( ) ;}

不能从这个定义实例化一个对象 但可以从它派生一个类 因此 该类必须实现ShowMyFace抽象方法

class CFace:IFace{  public void ShowMyFace( )   {    Console WriteLine( implementation ) ;   } }

基接口一个接口可以从零或多个接口继承 那些被称为这个接口的显式基接口 当一个接口有比零多的显式基接口时 那么在接口的定义中的形式为 接口标识符后面跟着由一个冒号 : 和一个用逗号 分开的基接口标识符列表

接口基 接口类型列表说明

· 一个接口的显式基接口必须至少同接口本身一样可访问 例如 在一个公共接口的基接口中指定一个私有或内部的接口是错误的

· 一个接口直接或间接地从它自己继承是错误的

· 接口的基接口都是显式基接口 并且是它们的基接口 换句话说 基接口的集合完全由显式基接口和它们的显式基接口等等组成 在下面的例子中

interface IControl { void Paint( ) ;}interface ITextBox: IControl { void SetText(string text) ;}interface IListBox: IControl { void SetItems(string[] items) ;}interface IComboBox: ITextBox IListBox { }

IComboBox 的基接口是IControl ITextBox 和 IlistBox

· 一个接口继承它的基接口的所有成员 换句话说 上面的接口IComboBox就像Paint一样继承成

员SetText 和 SetItems

· 一个实现了接口的类或结构也隐含地实现了所有接口的基接口

接口主体一个接口的接口主体定义接口的成员

lishixinzhi/Article/program/net/201311/11751

ServletContext application = new ServletContext();
如上这样写就是错的
但是ServletContext application = thisgetServletContext();这句话其实是一个向上转型,实际创建的是一个实现了ServletContext接口的类的对象,就相当于父类类型对象引用子类类型对象
即Father f = new Son();
PS:同学,我看你大概J2SE的基础知识还需要巩固一下,不要急于求成。j2se像反射、Annotation、线程、多态一类的只是还是挺重要的

public SomeClass someClass(){
return new ();
//前一个SomeClass是一个返回类型就是表明返回的类型是实现了这个接口的对象的引用,
//后一个someClass是方法名;
//return new ();这个是返回对象引用返回的这个对象必须是实现了SomeClass这个接口的对象的引用明白么

摘要
一, 接口基础知识
1, java语言不支持一个类有多个直接的父类(多继承),但可以实现(implements)多个接口,间接的实现了多继承
2, 与接口相关的设计模式:
1, 定制服务模式
设计精粒度的接口,每个接口代表相关的一组服务,通过继承来创建复合接口
2, 适配器模式
当每个系统之间接口不匹配时,用适配器来转换接口
3, 默认适配器模式
为接口提供简单的默认实现
4, 代理模式
为接口的实现类创建代理类,使用者通过代理来获得实现类的服务
5, 标识类型模式
用接口来标识一种没有任何行为的抽象类型
6, 常量接口模式
在接口中定义静态常量,在其它类中通过import static语句引入这些常量
3, 接口的特征归纳:
1, 接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
2, 接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化
public interface A
{
int CONST = 1; //合法,CONST默认为public,static,final类型
void method(); //合法,method()默认为public,abstract类型
public abstract void method2(); //method2()显示声明为public,abstract类型
}
3, 接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法
public interface A
{
int var; //错,var是常量,必须显示初始化
void method(){}; //错,接口中只能包含抽象方法
protected void method2(); //错,接口中的方法必须是public类型
static void method3(){}; //错,接口中不能包含静态方法
}
4, 接口中没有构造方法,不能被实例化
public interface A
{
public A(){}; //错,接口中不能包含构造方法
void method();
}
5, 一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口
public interface A
{
void methodA();
}
public interface B
{
void methodB();
}
public interface C extends A, B //C称为复合接口
{
void methodC();
}
public interface C implements A{} //错
6, 接口必须通过类来实现它的抽象方法
public class A implements B{}
7, 当类实现了某个接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象的
8, 不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
public class B implements A{}
A a = new B(); //引用变量a被定义为A接口类型,引用了B实例
A a = new A(); //错误,接口不允许实例化
9, 一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承
public class A extends B implements C, D{} //B为class,C,D为interface
4, 通过接口,可以方便地对已经存在的系统进行自下而上的抽象,对于任意两个类,不管它们是否属于同一个父类,只有它
们存在相同的功能,就能从中抽象出一个接口类型对于已经存在的继承树,可以方便的从类中抽象出新的接口,但从类
中抽象出新的抽象类却不那么容易,因此接口更有利于软件系统的维护与重构对于两个系统,通过接口交互比通过抽象
类交互能获得更好的松耦合
5, 接口是构建松耦合软件系统的重要法宝,由于接口用于描述系统对外提供的所有服务,因此接口中的成员变量和方法都
必须是public类型的,确保外部使用者能访问它们,接口仅仅描述系统能做什么,但不指明如何去做,所有接口中的方法
都是抽象方法,接口不涉及和任何具体实例相关的细节,因此接口没有构造方法,不能被实例化,没有实例变量二, 比较抽象类与接口
1, 抽象类与接口都位于继承树的上层
相同点
1, 代表系统的抽象层,当一个系统使用一颗继承树上的类时,应该尽量把引用变量声明为继承树的上层抽象类型,
这样可以提高两个系统之间的送耦合
2, 都不能被实例化
3, 都包含抽象方法,这些抽象方法用于描述系统能提供哪些服务,但不提供具体的实现
不同点:
1, 在抽象类中可以为部分方法提供默认的实现,从而避免在子类中重复实现它们,这是抽象类的优势,但这一优势
限制了多继承,而接口中只能包含抽象方法
由于在抽象类中允许加入具体方法,因此扩展抽象类的功能,即向抽象类中添加具体方法,不会对它的子类造
成影响,而对于接口,一旦接口被公布,就必须非常稳定,因为随意在接口中添加抽象方法,会影响到所有的实
现类,这些实现类要么实现新增的抽象方法,要么声明为抽象类
2, 一个类只能继承一个直接的父类,这个父类可能是抽象类,但一个类可以实现多个接口,这是接口的优势,但这
一优势是以不允许为任何方法提供实现作为代价的三, 为什么Java语言不允许多重继承呢
当子类覆盖父类的实例方法或隐藏父类的成员变量及静态方法时,Java虚拟机采用不同的绑定规则,假如还允许
一个类有多个直接的父类,那么会使绑定规则更加复杂,因此,为了简化系统结构设计和动态绑定机制,Java语言
禁止多重继承
而接口中只有抽象方法,没有实例变量和静态方法,只有接口的实现类才会实现接口的抽象方法(接口中的抽象方
法是通过类来实现的),因此,一个类即使有多个接口,也不会增加Java虚拟机进行动态绑定的复杂度因为Java虚
拟机永远不会把方法与接口绑定,而只会把方法与它的实现类绑定四, 使用接口和抽象类的总体原则:
1, 用接口作为系统与外界交互的窗口
站在外界使用者(另一个系统)的角度,接口向使用者承诺系统能提供哪些服务,站在系统本身的角度,接口制定
系统必须实现哪些服务,接口是系统中最高层次的抽象类型通过接口交互可以提高两个系统之间的送耦合
系统A通过系统B进行交互,是指系统A访问系统B时,
把引用变量声明为系统B中的接口类型,该引用变量引用系统B中接口的实现类的实例
public interface B
{
}
public class C implements B
{
}
public class A
{
}
B a = new C();
2, 接口本身必须非常稳定,接口一旦制定,就不允许随遇更加,否则对外面使用者及系统本身造成影响
3, 用抽象类来定制系统中的扩展点
抽象类来完成部分实现,还要一些功能通过它的子类来实现 2008/1/9
一, Java多态机制中的绑定规则深入剖析
class Base
{
String var = "BaseVar"; //实例变量
static String staticVar = "StaticBaseVar"; //静态变量 void method() //实例方法
{
Systemoutprintln("Base method");
} static void staticMethod() //静态方法
{
Systemoutprintln("Static Base method");
}
}public class Sub extends Base
{
String var = "SubVar"; //实例变量
static String staticVar = "StaticSubVar"; //静态变量
void method() //隐藏父类的method()方法
{
Systemoutprintln("Sub method");
} static void staticMethod() //隐藏父类的staticMethod()方法
{
Systemoutprintln("Static Sub method");
} String subVar = "Var only belonging to Sub"; void subMethod()
{
Systemoutprintln("method only belonging to Sub");
} public static void main(String args[])
{
//引用变量who被声明为Base类型,引用Sub类的实例
Base who = new Sub();
//成员变量(静态变量,实例变量)与引用变量所声明的类型(Base类型)的成员变量绑定
Systemoutprintln("whovar = "+whovar); //所以,打印Base类的var变量
Systemoutprintln("whostaticVar = "+whostaticVar); //所以,打印Base类的staticVar变量 //实例方法与引用变量实际引用的对象(Sub对象)的方法绑定
whomethod(); //所以,打印Sub实例的method()方法 //静态方法与引用变量所声明的类型(Base类型)的方法绑定
whostaticMethod(); //所以,打印Base类的staticMethod()方法
}
}
分析过程
1, 对于一个引用类型的变量,Java编译器按照它声明的类型来处理
例如在以下代码中,编译器认为who是Base类型的引用变量,不存在subVar成员变量喝subMethod()方法,编译报错
Base who = new Sub(); //引用变量who被声明为Base类型,引用Sub类的实例
whosubVar = "123"; //编译错,在Base类中没有subVar属性
whosubMethod(); //编译错,在Base类中没有submethod()方法
如果要访问Sub类的成员,必须通过强制类型转换:
Base who = new Sub();
//把Base引用类型的who成员变量强制转换为Sub引用类型
//把引用变量转换为子类的类型称为向下转型,把引用变量转换为父类的类型称为向上转型
((Sub)who)subVar = "123";
((Sub)who)subMethod();
Java编译器允许在具有直接或间接继承关系的类之间进行类型转换,对于向上转型,Java编译器会自动进行,对于
向下转型,需要进行强制类型转换
如果两种类型之间没有继续关系,即不在继承树的同一个继承分支上,那么Java编译器不允许进行类型转换
2, 对于一个引用类型的变量,运行时Java虚拟机按照它实际引用的对象来处理
例如以下代码虽编译可通过,但运行时会抛出ClassCastException运行时异常
Base who = new Base(); //who引用Base类的实例
Sub s = (Sub)who; //运行时会抛出ClassCastException
在运行时,子类的对象可以转换为父类类型,而父类的对象实际上无法转换为子类类型
3, 在运行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则:
1, 实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机
动态决定的
2, 静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经
绑定
3, 成员变量(静态变量,实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为
实际上是在编译阶段就已经绑定

接口其实就是类,当然能产生对象,接口产生的对象叫做方法而不叫做对象,只不过接口是比较特殊的类,一般用来直接与硬件对话你上面的语句其实就是创建一个comp对象但这个对象是某个类的私有成员变量


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12880650.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-28
下一篇2025-08-28

发表评论

登录后才能评论

评论列表(0条)

    保存