接口与抽象类

来源:互联网 发布:手机卡 非实名 淘宝 编辑:程序博客网 时间:2024/05/29 11:18

抽象类:

可以定义变量但是最少要有一个方法,当多个抽象类出现相同功能 但是功能主体不同

这是可以进行向上抽取 这事 只抽取功能定义 而不抽取功能主体必须有一个抽象类方法 抽象类方法没有主体

抽象:模糊 看不懂

抽象类的特点:

1.抽象方法一定在抽象类中 

2.抽象方法和抽象类都必须备abstrct关键字修饰

3.抽象类不可以用new创建对象 因为调用抽象类方法没意义

4.抽象类中的方法要被使用 必须由子类重写主类的功能主体 然后建立子类对象调用

如果子类只覆盖了部分抽象方法 那么该子类还是一个抽象类

抽象类和一般类没有太大的不同

1.方法只有声明没有实现时 该方法就是抽象方法 需要被absstatic修饰

抽象类方法必须定义在抽象类中 该类也必须被absstatic修饰

2.抽象类不可以被实例化,为什么?

抽象类是个模糊的概念如果实例化 抽象类就不能达到效果 

该如何描述事物 就如何描述事物 只不过 该事物中出现了看不懂的东西

这些不确定的部分 也是该事物的功能 需要明确出现 但是无法定义主体

抽象类比一般类多了抽象函数 可以在类中定义抽象方法

抽象只能修饰类和方法 

抽象类不可以实例化


特殊:

抽象类中可以不定义抽象方法  这样做仅仅是不让该类建立对象

抽象类中不可以喝那些关键字共存:

private:私有 [因为如果将抽象方法私有后 子类无法覆盖 也无法调用]

static:静态[如果使用了静态后 就不需要对象了 直接类名调用 但是只能抽象方法运行 子类不能运行 则无意义]

final:最终的:[如果修饰了抽象方法则多个子类无法覆盖]

抽象类和一般类:

相同点:

都是用来描述事物的 都在内部定义了成员

不同点:

1.一般类有足够的信息描述事物,抽象类描述的事物信息不足

2.一般类中不能定义抽象方法,抽象类中可定义抽象方法 也可以定义非抽象方法

3.一般类可以被实例化,抽象类不能被实例化,抽象类必须是一个父类 因为需要子类的覆盖方法才可以实例化


1.接口:

(1)当一个类中的方法都是抽象的时候,Java提供了另一种表示方式,叫接口。

  用interface关键字表示。类与接口关系用implements表示。
(2)接口的成员特点
A:成员变量
是常量,默认修饰 public static final
B:成员方法
都是抽象的,默认修饰 public abstract
(3)关系
A:类与类的关系
是继承关系。类与类只能单继承,可以多重继承。
B:类和接口的关系
是实现关系。类可以多实现接口。
类在继承一个类的同时,可以实现多个接口。
C:接口和接口的关系
是继承关系。接口可以多继承接口。
(4)接口的特点
A:是对外暴露的规则
B:是功能的扩展
C:接口的出现降低耦合性。
耦合(类与类之间的关系)
内聚(类完成功能的能力)
编程规范:低耦合,高内聚。
D:接口可以多实现。如:CPU和主板、笔记本的USB插口、插座
(5)接口和抽象类的区别
A:抽象类只能被单继承
  接口可以多实现,接口的出现避免了多继承的局限性。
B:抽象类中的数据特点:
成员变量:可以是变量,也可以是常量
成员方法:可以是抽象方法,也可以是非抽象方法
构造方法:有构造方法
  接口中的数据特点:
成员变量:是常量。默认修饰 public static final
成员方法:都是抽象方法。都有默认修饰 public abstract
构造方法:没有构造方法
C:抽象类中定义的是继承体系中的共性功能。
  接口中定义的是继承体系中的扩展功能。
D:抽象类被继承是"is a"关系:xx是yy的一种
  接口被实现是"like a"关系:xx像yy的一种


定义接口格式:

[public]interface 接口名称 [extends父接口名列表]

{

//静态常量

[public] [static] [final] 数据类型变量名=常量值;

//抽象方法

[public] [abstract] [native] 返回值类型方法名(参数列表);

}


实现接口格式:

[修饰符] class 类名[extends 父类名] [implements 接口A,接口B,···]

{

类成员变量和成员方法;

为接口A中的所有方法编写方法体,实现接口A;

为接口B中的所有方法编写方法体,实现接口B;

}

代码:

[java] view plain copy
 print?
  1. /*  
  2.  * Java里面的接口回调,最简单的情况示意如下  
  3.  */    
  4. interface A {}    
  5.     
  6. class B implements A {}    
  7.     
  8. class C implements A {}    
  9.     
  10. class Test {    
  11.     A b = new B();    
  12.     A c = new C();    
  13. }    
  14.     
  15. /*  
  16. 我们重点关注——用Java接口实现回调函数的等价功能  
  17. 简单来说,就是某个类的某个函数,接收一个接口作为参数(或者直接把该接口作为field),  
  18. 那么就可以在这个函数中调用接口里面的方法了,称为回调  
  19. 而接口的实现可以千变万化,将不同的接口的实现类传入,就可实现不同的功能  
  20.   
  21. 例如:  
  22. */    
  23. interface Hello {    
  24.     void sayHello();    
  25. }    
  26.     
  27. class Man {    
  28.         
  29.     private Hello hello;    
  30.         
  31.     public Man(Hello hello) {    
  32.         this.hello = hello;    
  33.     }    
  34.         
  35.     public void say() {    
  36.         hello.sayHello();    
  37.     }    
  38.         
  39. }    
  40.     
  41. class HelloTest {    
  42.         
  43.     public static void test() {    
  44.         Man chinese = new Man(new Hello() {    
  45.            public void sayHello() {    
  46.                System.out.println("你好");    
  47.            }    
  48.         });    
  49.         chinese.say();    
  50.             
  51.         Man english = new Man(new Hello() {    
  52.             public void sayHello() {    
  53.                 System.out.println("hello");    
  54.             }    
  55.         });    
  56.         english.say();    
  57.     }    
  58. }    
  59.     
  60.     
  61.     
  62. /*  
  63.  * 上面的例子是调用类“拥有接口”,接口是不知道调用类的  
  64.  * 若接口和调用类要交互,那他们就是相互“拥有”  
  65.  * 考虑这样一个应用: NameChanger动态地改变Client的名字  
  66.  * 那NameChanger的changeName方法就要接收一个Client对象,然后获取(调用)Client的名字并作不同的处理  
  67.  * Client也要持有NameChanger,因为要打印改变后的名字  
  68.  */    
  69. class Client {    
  70.     
  71.     private INameChanger changer;    
  72.     private String clientName;    
  73.         
  74.     
  75.     public Client(INameChanger changer) {    
  76.         this.changer = changer;    
  77.     }    
  78.     
  79.     public void changeNameNow() {    
  80.         String newName = changer.changeName(this);    
  81.         this.clientName = newName;    
  82.     }    
  83.         
  84.     public String getName() {    
  85.         return clientName;    
  86.     }    
  87.     
  88.     public void setName(String clientName) {    
  89.         this.clientName = clientName;    
  90.     }    
  91.         
  92.     
  93. }    
  94.     
  95. interface INameChanger {    
  96.         
  97.     String changeName(Client client);    
  98.         
  99. }    
  100.     
  101.     
  102. class ChangeNameTest {    
  103.         
  104.     public static void test() {    
  105.             
  106.         Client client = new Client(new INameChanger(){    
  107.             public String changeName(Client client) {    
  108.                 return "Mr." + client.getName();    
  109.             }    
  110.         });    
  111.         client.setName("Tom");    
  112.         client.changeNameNow();    
  113.         System.out.println(client.getName());    
  114.             
  115.         Client client2 = new Client(new INameChanger(){    
  116.             public String changeName(Client client) {    
  117.                 return "Miss." + client.getName();    
  118.             }    
  119.         });    
  120.         client2.setName("Lucy");    
  121.         client2.changeNameNow();    
  122.         System.out.println(client2.getName());    
  123.             
  124.     }    
  125.         
  126. }    
  127.     
  128.     
  129. /*  
  130.  * 考虑这样一个应用:希望在某个事件发生时得到通知  
  131.  */    
  132. interface InterestingEvent {    
  133.         
  134.     public void interestingEvent();    
  135.         
  136. }    
  137.     
  138.     
  139. class EventNotifier {    
  140.         
  141.     private InterestingEvent event;        //写成private List<InterestingEvent> eventList可以监听多个事件    
  142.     private boolean somethingHappened;    
  143.         
  144.     public EventNotifier(InterestingEvent ie) {    
  145.         this.event = ie;    
  146.         this.somethingHappened = false;    
  147.     }    
  148.         
  149.     public void setHappened() {    
  150.         this.somethingHappened = true;    
  151.     }    
  152.         
  153.     public void doWork() {    
  154.         if (somethingHappened) {    
  155.             event.interestingEvent();    
  156.         }    
  157.     }    
  158.         
  159. }    
  160.     
  161.     
  162. class ButtonPressedEvent implements InterestingEvent {    
  163.     
  164.     @SuppressWarnings("unused")    
  165.     private EventNotifier en;    
  166.         
  167.     public ButtonPressedEvent() {    
  168.         en = new EventNotifier(this);    
  169.     }    
  170.         
  171.     public void interestingEvent() {    
  172.         System.out.println("button pressed ");    
  173.     }    
  174.         
  175. }    
  176.     
  177.     
  178. class EventNotifierTest {    
  179.         
  180.     public static void test() {    
  181.         //这里有两种调用方法。其中第二种采用匿名内部类,其原理跟上面“改变Client名字”是一样的    
  182.         EventNotifier en = new EventNotifier(new ButtonPressedEvent());    
  183.         en.setHappened();    
  184.         en.doWork();    
  185.             
  186.         EventNotifier en2 = new EventNotifier(new InterestingEvent(){    
  187.             public void interestingEvent() {    
  188.                 System.out.println("inputtext change ");    
  189.             }    
  190.         });    
  191.         en2.setHappened();    
  192.         en2.doWork();    
  193.             
  194.     }    
  195. }    
  196.     
  197.     
  198. //这个类是用来测试的    
  199. public class JavaInterfaceCallBack {    
  200.         
  201.     public static void main(String[] args) {    
  202.         HelloTest.test();    
  203.         ChangeNameTest.test();    
  204.         EventNotifierTest.test();    
  205.             
  206.     }    
  207.     
  208. }    
这里提一下final关键子:

final:

最终 作为一个修饰符

1.可以修饰类,函数,变量

2.被final修饰的类不可以被继承 为了避免被继承 被子类重写功能

3.被fianl修饰的方法  不可以被重写[覆盖]

4.被fianl修饰的变量是个常量只能赋值一次 即可以修饰成员变量 也可以修饰局部变量

[当在描述事物时 一些数据的出现值是固定的 那么这时为了增强阅读行 都给这些值赋值名字方便运行

而这个值不需要改变 所以加上 fiaal  作为常亮的书写规范所有字母都大写 如果由多个字母组成单词间通过_连接]




0 0