`

3、类与对象之抽象类、接口、内部类

    博客分类:
  • java
阅读更多
抽象类与接口:
这两个概念总是被放在一起讨论,因为他们有很多相似的地方,可以说接口本身就是完全抽象的,它要比抽象类更加“抽象”,为什么这么说?抽象类是一种类,里面除了有抽象方法外,还可以有具体的方法,而接口里面必须都是抽象的方法(有时可以在接口里定义类,后面会讲),尽管有时并没有显示的用abstract 关键字声明。此处我们提到抽象方法,在Java中,凡是声明为形如:abstract void function()的方法,都是抽象方法,包含抽象方法的类就是抽象类,可以这么总结:抽象类中是可以全是实体方法;也可以全是抽象方法。有抽象方法的类必须是抽象类;

当我们继承抽象类时,必须重写其抽象方法,所以抽象类不能被声明为final类型的,因为加final关键字的类保证不能被继承,抽象类只能被继承,不能被实例化(只要是abstract声明的类)!
声明为interface的类为接口,比抽象类更加抽象的一种机制。在接口中,我们不能提供任何实现,所有方法必须都是抽象的,可以不加 abstract关键字,但是编译器对于接口中的方法,都是直接按抽象方法处理的。我们通过implements来实现某个接口。当我们实现某个接口时, 必须重写其所有方法。

Java多接口实现

interface为我们提供了一种将抽象方法与实体方法分离的结构,但是interface的作用远不止此,在Java中接口解决了一个非常重要的问题:多继承。在C++中,实现多重继承是比较简单的事儿,但是Java继承机制不允许多重继承,所以如果想要整合不同类的功能,就需要使用接口:
总结下使用接口的好处:
1、接口可以实现向上转型,多个具有共同属性的类可以将它们的共同点提取出来,做成抽象,这样层次分明,统一管理。

class A implements interA,interB,interC{ 
       @overide  
        somemethod(){... ...} 

class B{ 
       method(interA a){a.fun1()}; 
       method(interB a){a.fun2()}; 
       method(interC a){a.fun3()}; 
       main(){method(new A);} 

两个接口定义一样的方法被同一个类实现,调用执行时是同一个方法; 

2、接口不具有任何实体方法,最适合做基类。
总结一下抽象类与接口的区别和联系:
a)  抽象类是类,可以有实体方法。
b)  抽象类不能实现多继承,而接口可以。
c)  如果需要创建不带任何方法定义和成员变量的基类,则使用接口,如果类中需要有部分具体的实现,则使用抽象类。

d)  如果事先想要将某类设计为一个基类,那么首选接口。
接口可以通过继承(extends)接口,来拓展功能。
接口中的变量(域)默认是public  final static 的
因此在interface中声明的变量建议大写的,声明的时候必须初始化,使用的时候不能被更改
显式声明的 public  final static String NAME;
隐式声明的 String NAME;

内部类
内部类的意思就是将类的定义放在另一个类的内部。有时合理的内部类使用会使代码更加简洁,令程序更加巧妙。作为外部类的成员,内部类可以访问外部类私有的成员变量。我们先来看看内部类的创建,分这么几种情况:
1、在外部类非静态方法 创建内部类实例。
class InnerClass {   
    class A{   
        int a = 10;   
        void b(){   
            System.out.println("this is A.b()!");   
        }   
    }   
    A getA(){ 
      A a=new A();        
      return a;        //外部通过调用该方法得到局部方法的值,局部变量a在外面失效; 
    } 

public class Extends {   
  public static void main(String[] args){      
      new InnerClass().getA().b(); 
  } 
}  
2、在外部类的静态方法中创建内部类的实例。
当在外部类的静态方法中创建内部类时,内部类也必须是静态的,形如:static  class  A{  },
这里为什么class A 一定要加上static?
Java代码  收藏代码
public class InnerClass {   
    static class A{   
        int a = 10;   
        void b(){   
            System.out.println("this is A.b()!");   
        }   
    }   
    public static void main(String[] args) {   
        InnerClass.build().b();   
    }   
    static A build(){    //静态方法要被调用时才被执行,与静态块不一样 
        A a =new A();      
        return a; 
    }   
}  
  当内部类是非静态的:

public class InnerClass {   
    class A{   
        int a = 10;   
        void b(){   
            System.out.println("this is A.b()!");   
        }   
    }      
    public static void main(String[] args) {   
        InnerClass ic = new InnerClass();   
        InnerClass.A aa = ic.new A();   
        aa.b();   
    }   
}   
3、在内部类的非静态方法中创建外部类的实例。(使用外部类.this来创建外部类的实例)
这里为什么内部类能创建外部类?应该和Jvm机制有关,在后面的章节详解

public class InnerClass {   
    class A{   
        int a = 10;   
        void build(){   
            InnerClass ic = InnerClass.this;   //这个this是构造方法 
            ic.a();   
        }   
    }   
    void a(){   
        System.out.println("this is InnerClass.a()!");   
    }   
}   
4、在内部类的静态方法中创建外部类的实例。(直接通过new来创建)

public class InnerClass {   
    static class A{   
        int a = 10;   
        static void build(){   
            InnerClass ic = new InnerClass();   
            ic.a();   
        }   
    }       
    void a(){   
        System.out.println("this is InnerClass.a()!");   
    }   
}  
5、其他类中创建内部类实例

class B {   
    class A{   
        void a(){   
            System.out.println("this is A.a()!");   
        }   
    }   
    static class C{   
        void c(){   
            System.out.println("this is C.c()!");   
        }   
    }   
}   
public class AKL{   
    public static void main(String[] args){   
        /*创建非静态内部类*/   
        B ic = new B();   
        B.A a = ic.new A();   
        a.a();   
           
        /*创建静态内部类*/   
        B.C c = new B.C();   
        c.c();   
    }   
}   
看个深层嵌套的:

public class ABC {   
    void a() {   
        System.out.println("this is A.a()!");   
    }   
   
    class B {   
        void b() {   
            System.out.println("this is B.b()!");   
        }   
        class C {   
            void c() {   
                a();   
                b();   
                System.out.println("this is C.c()!");   
            }   
        }   
    }   
    public static void main(String[] args) {   
        ABC abc = new ABC();   
        ABC.B b = abc.new B();   
        ABC.B.C c = b.new C();   
        c.c();   
    }   
}   
&&:此处最重要的就是这个”.new”操作符。同时,在类C内部调用a()和b()都很轻松,就说明内部类就相当于一个普通的变量,即使是private权限的,也一样直接调用,因为它们在同一个类中。

匿名内部类的创建:

interface A {   
    void a();   
}   
   
public class InnerClass_NoName {   
    public A test() {   //内部类为接口A的实现类(方法内部类) 
        return new A() {   
            public void a() {   
                System.out.println("");   
            }   
        };   
    }   
   
    public static void main(String[] args) {   
        InnerClass_NoName icn = new InnerClass_NoName();   
        A a = icn.test();   
        a.a();    //a可以调用匿名内部类,实现接口方法的向上转型 
    }   
}   
典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。一般情况,内部类不宜过长,否则就会显得头重脚轻。

使用匿名内部类应该注意:
a)        匿名内部类不能有构造方法
b)        匿名内部类不能定义任何静态成员、方法和类。
c)         匿名内部类不能是public,protected,private,static。
d)        只能创建匿名内部类的一个实例。
e)        一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。

f)         因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。


内部类分为成员内部类、静态嵌套类、方法内部类、匿名内部类。
几种内部类的共性:
A、内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号。
B、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
Java代码  收藏代码
1、成员内部类:形式如下 
    class Outer { 
        class Inner{} 
    }        
编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。 
成员内部类内不允许有任何静态声明!下面代码不能通过编译。 
    class Inner{ 
        static int a = 10; 
    }  
从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部,因此也被称为顶级嵌套类。
静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类不能访问外部类的成员和方法。
public class InnerClass {   
    static class A{   
        static int a = 10;   
        static void a(){   
            System.out.println("this is A.a()!");   
        }   
    }   
}   
接口内部类:
public interface Interface_Class {   
    void say();   
    class IC implements Interface_Class{   
        @Override   
        public void say() {   
            System.out.println("hello");   
        }   
         
    }   
}   
适合于创建公共代码,供所有实现了该接口的类使用。
内部类的继承,我们说过,内部类持有对外部类的引用,所以,在继承的时候,我们需要初始化这个“隐藏”着的引用,请看下面的代码:
class AAA {   
    class BBB {    
    }   
}   
public class InnerClass_Extends extends AAA.BBB {   
    public InnerClass_Extends(AAA aaa) {   
        aaa.super();   
    }   
    public static void main(String[] args) {   
        AAA aaa = new AAA();   
        InnerClass_Extends ice = new InnerClass_Extends(aaa);   
    }   
}  
最后,我们总结下使用内部类的原因:每个内部类都能独立继承自一个接口的实现,和外部类没有任何关系(不论外部类是否实现了该接口)。
说的再简单一点就是,内部类是Java多继承机制的完美补充,如果现在非得用抽象类实现多继承,很明显是不可能的,此处就必须使用内部类。

铅笔类 
public abstract class Pencil { 
  public abstract void write(); 

橡皮擦类 
public abstract class Eraser { 
  public abstract void erase(); 
}  
带橡皮擦的铅笔类: 
public class PencilWithEraser {      
    private MyPencil pencil = new MyPencil();    
    private MyEraser eraser = new MyEraser();    
    private class MyPencil extends Pencil {    
        public void write() {    
            System.out.println("Use to write");    
        }    
    }    
    private class MyEraser extends Eraser {    
        public void erase() {    
            System.out.println("Use to erase");    
        }    
    }    
    public void write() {    
        pencil.write();    
    }    
    public void erase() {    
        eraser.erase();    
   
分享到:
评论

相关推荐

    接口,内部类,抽象类概念和区别

    在编程世界中,接口、内部类和抽象类是面向对象设计的重要组成部分,它们各自具有独特的功能和用途。本文将深入探讨这些概念以及它们之间的区别。 首先,我们来了解**接口**。接口在Java中是一种完全抽象的类型,它...

    C#类、接口、虚方法和抽象方法-抽象类和接口的相同点和区别

    这里我们将详细讨论这些概念以及抽象类与接口之间的相同点和区别。 首先,让我们来看看抽象类(Abstract Class): 1. 抽象方法是只有声明没有实现的方法,可以视为没有方法体的虚方法。例如: ```csharp public ...

    抽象类、接口、内部类、异常

    总结,抽象类、接口、内部类和异常是Java面向对象编程的重要组成部分,它们提供了不同层次的抽象和组织代码的方式,同时异常处理确保了程序在遇到问题时能够优雅地恢复或结束。理解并熟练运用这些概念对于编写健壮、...

    面向对象进阶(抽象类、接口、内部类)例题

    本知识点将深入探讨面向对象编程中的三个重要概念:抽象类、接口以及内部类,并通过实例解析它们的使用和作用。 1. 抽象类(Abstract Class) 抽象类是不能被实例化的类,它用来作为其他类的基类,提供公共的属性...

    接口与抽象类区别

    接口与抽象类区别 在软件开发中,接口和抽象类是两个常用的概念,但它们之间的区别却让许多人感到困惑。那么,什么是抽象类和接口?它们之间有什么区别?下面,我们就来详细地探讨这个问题。 一、抽象类 抽象类是...

    java学习资料抽象类,接口,内部类

    在这个Java学习资料中,我们重点探讨抽象类、接口和内部类。 首先,抽象类是一种不能实例化的类,它主要用于被其他类继承。在Java中,使用`abstract`关键字来定义一个抽象类。抽象类可以包含抽象方法(无方法体的...

    浅析Java抽象类和接口的比较

    Java中的抽象类(abstract class)和接口(interface)都是用于创建抽象化模型的重要工具,它们在面向对象编程中扮演着核心角色。这两种机制都允许我们定义一组方法的签名,但不提供具体实现,从而实现“设计契约”...

    java期末复习抽象类与接口,内部类,知识点.zip

    在Java的学习过程中,抽象类、接口以及内部类是三个非常关键的概念,它们对于理解和实现复杂的软件架构至关重要。这里我们将深入探讨这些概念。 首先,让我们来看看抽象类。在Java中,抽象类是一种不能被实例化的类...

    抽象类与接口中方法的相同点和不同点

    抽象类与接口中方法的相同点和不同点 抽象类和接口是Java编程语言中两种基础的编程概念,它们都是用于实现多态性和继承性的重要工具。在这篇文章中,我们将详细讨论抽象类和接口中方法的相同点和不同点。 抽象类 ...

    java实验四 对象和类(抽象类、接口与包).doc

    Java 实验四 对象和类(抽象类、接口与包) 本实验主要涉及到 Java 中的对象和类的概念,包括抽象类、接口、包等面向对象程序设计技术的特点。通过本实验,学习者将熟练掌握抽象类、接口、包的概念,并了解如何使用...

    java中的抽象类,接口和内部类 PPT

    在Java编程语言中,抽象类、接口和内部类是三个重要的概念,它们分别用于不同的设计需求。下面将详细解释这三个概念及其使用。 1. 抽象类(Abstract Class) 抽象类是不能直接实例化的类,它包含至少一个抽象方法。...

    C#接口抽象类区别实例

    (5) 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性 (6) 接口基本上不具备继承的任何具体特点,它仅仅承诺了...

    C#面向对象之接口和抽象类详解

    ### C#面向对象之接口和抽象类详解 #### 一、接口 **1. 概念** 接口在C#中是一种特殊类型的类,它定义了一种协议,即一组相关的行为和属性,这些行为和属性可以被任何类或结构实现。接口可以包含方法、属性、事件...

    抽象类和接口

    ### 抽象类和接口详解 ...总结来说,抽象类和接口都是面向对象编程中非常重要的概念,它们帮助开发者更好地组织代码结构、提高代码的复用性和灵活性。正确理解和使用这些概念对于编写高质量的 Java 应用程序至关重要。

    抽象类和抽象方法、接口

    4. **具体与抽象**:抽象类更多地体现了类的内部共性,而接口强调的是类的外部特性。 5. **接口的灵活性**:接口可以被用来支持回调机制,而继承不具备这种特点。 6. **方法的虚与非虚**:抽象类实现的具体方法...

    Java中抽象类和接口的区别与作用详解

    ### Java中抽象类和接口的区别与作用详解 #### 一、引言 在Java编程语言中,`abstract class`和`interface`是两种用于定义抽象类的重要机制。这两种机制不仅支持了Java的强大面向对象特性,而且也在实际开发过程中...

    接口与抽象类的主要区别

    在编程领域,接口和抽象类是面向对象设计中两种重要的机制,它们用于定义类的行为和结构。虽然两者在某些方面有相似之处,但它们在概念、实现方式和用途上存在显著差异。 首先,抽象类是一种特殊的类,它不能被实例...

    浅析Java抽象类与接口的区别.zip

    在Java编程语言中,抽象类和接口是两种重要的面向对象设计概念,它们都用于实现多态性,但各自具有不同的特点和应用场景。本篇文章将详细分析这两种机制的区别,以帮助开发者更好地理解和运用。 首先,抽象类是类的...

    JAVA设计模式(抽象类与适配器模式)

    今天我们要探讨的是JAVA设计中的两个重要模式:抽象类与适配器模式。 首先,我们来理解一下“抽象”。抽象是面向对象编程的核心概念之一,它帮助我们处理对象的复杂性。在Java中,抽象通常通过抽象类来实现。抽象类...

Global site tag (gtag.js) - Google Analytics