精华内容
参与话题
问答
  • 抽象类的定义与使用

    千次阅读 多人点赞 2019-04-03 14:38:22
    抽象类 ##1.抽象类的定义与使用 **抽象类:**在普通类的基础上扩充了一些抽象方法(0~n)的类(抽象类是普通类的超集),使用abstract关键字定义。 抽象类不能直接产生实例化对象,因为抽象类是“半成品”,无法直接...

    抽象类

    ##1.抽象类的定义与使用

    **抽象类:**在普通类的基础上扩充了一些抽象方法(0~n)的类(抽象类是普通类的超集),使用abstract关键字定义。

    抽象类不能直接产生实例化对象,因为抽象类是“半成品”,无法直接使用。不能直接new

    **抽象方法:**使用abstract 关键字定义并且没有方法体的方法。抽象方法所在类一定是抽象类。

    abstract class Person{
        public abstract void print();//抽象方法
    }
    public native void test();//本地方法(调用C或者其他语言同名方法)。也没有方法体
    

    2.抽象类的使用原则

    1)所有抽象类必须有子类 :(abstract与final不能同时出现,编译出错)

    //抽象类的定义与使用
    abstract final class Person{//此处报错  abstract与final关键字不能同时出现
        static int num=10;
        public abstract void print();
    } 
    public class Test16{
        public static void main(String[] args){
            System.out.println(Person.num);
        }
    }
    

    在这里插入图片描述
    2) 如果子类不是抽象类 ,子类必须覆写抽象类(父类)的所有抽象方法。(子类是抽象类则可以不要求全部覆写)

    abstract class Person{
        abstract void print();
        abstract void fun();
    }
    class Student extends Person{
        static int num=10;
        public void print(){}
        //public void fun(){}//报错
    }
    public class Test17{
        public static void main(String[] args){
           // Person per = new Student();
           //Student stu = new Student(); 
        System.out.println(Student.num);
        }
    }
    

    在这里插入图片描述
    3)抽象类可以使用子类向上转型对其实现实例化,抽象类一定不能直接实例化对象(无论是否有抽象方法)

    abstract class Person{
       public abstract void print();
      
    }
    class Student extends Person{
        public void print(){
            System.out.println("hello i am student");
        }
    }
    public class Test19{
        public static void main(String[] args){
            //Person per = new Student();
            Person per = new Person();//此处报错
            per.print(); 
        }
    }
    

    在这里插入图片描述

    //正确写法:
    public class Test19{
        public static void main(String[] args){
            Person per = new Student();//正确写法  由子类向上转型实现实例化
            per.print(); 
        }
    }
    

    4)由于抽象类强制要求子类覆写父类方法,所以private 与 abstract 不能同时使用。(private 修饰私有属性,被private修饰的属性和方法不能被外部使用)

    abstract class Person{
       private abstract  void print();//此时报错  private 与 abstract不能同时使用
    }
    class Student extends Person{
         public void print(){
         System.out.println("hello world");
       }
    }
    public class Test18{
        public static void main(String[] args){
            Person per = new Student();
        }
    } 
    

    在这里插入图片描述

    抽象类的相关规定

    1).抽象类也存在抽象方法,并且子类也一定按照构造实例化流程。先调用抽象类构造方法,再调用子类构造方法。

    abstract class Person{
        private String  name;//属性
        public Person(){
           System.out.println("父类构造方法!");
        }
        public void setName(String name){//普通方法
           this.name=name;
        }
        public String getName(){//普通方法
           return name;
        }
        public abstract void print();//抽象方法
    }
    class Student extends Person{
        private int age;
        public Student(){//子类构造方法
           System.out.println("子类构造方法!");
        }
    
        public void setAge(int age){//子类普通方法
            this.age=age;
        }
        public int getAge(){//子类普通方法
            return age;
        }
        public void print(){//子类覆写的父类抽象方法
        //空实现
        }   
    }
    public class Test20{
        public static void main(String[] args){
            new Student();
        }
    }
    

    在这里插入图片描述
    2).特殊代码

    abstract class A{
        public A(){//3.调用父类构造方法
            this.print();//4.调用父类方法,方法被子类覆写
        }
        public abstract void print();
    }
    class B extends A{
        private int num=100;
        public B(int num){//2.调用子类构造方法
            super();//3.隐含调用父类构造方法
            this.num=num;//为类中属性初始化
        }
        public void print(){//5.调用覆写后的方法。此时子类对象的属性没有被初始化(对象初始化操作在构造方法中执行)
            System.out.println(this.num);//6.打印数据为数据类型的默认值
        }
    }
    public class Test21{
        public static void main(String[] args){
            new B(30);//1.实例化子类对象
            new B(30).print();//修改代码后
        }
    }
    

    在这里插入图片描述
    结果为 0 原因:此时子类对象的属性没有被初始化,即没有进入子类的构造方法中。

    3).补充:关于对象实例化:对象的实例化操作有以下几个核心步骤:

    • ·进行类加载
    • 进行类对象的空间开辟
    • 进行类对象中属性初始化(构造方法)

    4).抽象类中允许不定义任何抽象方法,此时该抽象方法仍然不能直接创建实例化对象

    abstract class Person{
        private int num;
        public void fun(){
            System.out.println("*******");
        }
    }
    class Student extends Person{
        public void fun(){
            System.out.println("&&&&&&&");
        }
    }
    public class Test22{
        public static void main(String[] args){
            Person per = new Person();//此处报错
        }
    }
    

    在这里插入图片描述

    5). 抽象类一定不能使用final 关键字声明,因为用final声明的类不允许有子类,而抽象类必须有子类;

    抽象类一定不能使用private 关键字声明,因为private 关键字表示封装,内部操作外部不可见,而抽象方法 必须被覆写。

    6).抽象类也分内部抽象类和外部抽象类。内部抽象类的抽象方法与外部抽象类的抽象方法无关。**当前直接继承哪个抽象类,就覆写其抽象方法。**即:若直接继承外部抽象类,则只需覆写外部抽象类的所有抽象方法即可

    abstract class A{//外部抽象类
        public abstract void fun();
        abstract class AInner{//内部抽象类
           abstract void fun1();
        }
    }
    class B extends A{//子类
        public void fun(){//只覆写外部类的抽象方法
            System.out.println("0000");
        } 
    }
    public class Test23{
        public static void main(String[] args)        
        }
    }
    //此时程序不报错
    
    //修改程序
    class B extends A{
        /*public void fun(){
            System.out.println("0000");
        } */
        public void fun1(){};//覆写内部抽象类的抽象方法 程序报错
    }
    

    在这里插入图片描述

    //要覆写内部抽象类抽象方法 正确写法
    abstract class A{
        public abstract void funA();
        abstract class AInner{
            public abstract void funB();
        }
    }
    class B extends A{
        public void funA(){};
        class BInner extends AInner{
            public void funB(){};
        }
    }
    public class Test24{
        public static void main(String[] args){
    
        }
    }
    

    7).外部类抽象类不允许使用static ,内部类抽象类可以使用static

    abstract class A{
        public abstract void print();
        static abstract class B{//内部抽象类
            public abstract void printB();
        }
    }
    class C extends A.B{
        public void printB(){};
    }
    public class Test25{
        public static void main(String[] args){
          C c = new C(); 
        }
    }
    
    展开全文
  • 什么是抽象类

    千次阅读 多人点赞 2018-04-10 17:26:20
    1.抽象类的定义:抽象就是从多个事物中将共性的,本质的内容抽取出来。 2.抽象方法的由来:多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有...

    1.抽象类的定义:抽象就是从多个事物中将共性的,本质的内容抽取出来。

    2.抽象方法的由来:多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的 方法称为抽象方法。

    2.1例子:例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。

    3.抽象类的特点:

    3.1:抽象方法只能定义在抽象类中,抽象的方法和抽象的类必须由关键字abstract修饰。

    3.1:抽象类值只定义方法声明,不定义功能主题(即方法的实现)。

    3.2:抽象类不可以被创建对象。

    3.3;抽象类只有子类继承了父类中的方法,并且对其中的所有抽象方法进行了重写。该子类才不是抽象类,只要不是重写当中的所有抽象方法,那么这个子类还是抽象类

    4.注意点:

    4.1:抽象类中是否有构造函数?有,用于给子类对象进行初始化。

    4.2:抽象类中是否可以定义非抽象方法?可以

    4.3:抽象关键字abstract和哪些不可以共存?final , private , static 

    4.4::抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。

    展开全文
  • Java抽象类 详解

    万次阅读 多人点赞 2016-10-05 00:06:35
    一、抽象类的基本概念普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。...

    一、抽象类的基本概念

    普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。

    那么什么叫抽象方法呢?在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰

    拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。

    范例:定义一个抽象类

    abstract class A{//定义一个抽象类
    	
    	public void fun(){//普通方法
    		System.out.println("存在方法体的方法");
    	}
    	
    	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
    	
    }
    

    二、抽象类的使用

    我们先看范例。
    范例:直接实例化抽象类的对象

    package com.wz.abstractdemo;
    
    abstract class A{//定义一个抽象类
    	
    	public void fun(){//普通方法
    		System.out.println("存在方法体的方法");
    	}
    	
    	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
    	
    }
    
    public class TestDemo {
    
    	public static void main(String[] args) {
    		A a = new A();
    	}
    }
    

    运行:

    Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    	Cannot instantiate the type A
    
    	at com.wz.abstractdemo.TestDemo.main(TestDemo.java:15)
    
    

    从上可知,A是抽象的,无法直接进行实例化操作。为什么不能直接实例化呢?当一个类实例化之后,就意味着这个对象可以调用类中的属性或者放过了,但在抽象类里存在抽象方法,而抽象方法没有方法体,没有方法体就无法进行调用。既然无法进行方法调用的话,又怎么去产生实例化对象呢。

    抽象类的使用原则如下:
    (1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
    (2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
    (3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
    (4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);

    范例:

    package com.wz.abstractdemo;
    
    abstract class A{//定义一个抽象类
    	
    	public void fun(){//普通方法
    		System.out.println("存在方法体的方法");
    	}
    	
    	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
    	
    }
    //单继承
    class B extends A{//B类是抽象类的子类,是一个普通类
    
    	@Override
    	public void print() {//强制要求覆写
    		System.out.println("Hello World !");
    	}
    	
    }
    public class TestDemo {
    
    	public static void main(String[] args) {
    		A a = new B();//向上转型
    		
    		a.print();//被子类所覆写的过的方法
    	}
    }
    
    

    运行结果:

    Hello World !
    
    

    现在就可以清楚的发现:
    (1)抽象类继承子类里面有明确的方法覆写要求,而普通类可以有选择性的来决定是否需要覆写;
    (2)抽象类实际上就比普通类多了一些抽象方法而已,其他组成部分和普通类完全一样;
    (3)普通类对象可以直接实例化,但抽象类的对象必须经过向上转型之后才可以得到。

    虽然一个类的子类可以去继承任意的一个普通类,可是从开发的实际要求来讲,普通类尽量不要去继承另外一个普通类,而是去继承抽象类。

    三、抽象类的使用限制

    (1)抽象类中有构造方法么?
    由于抽象类里会存在一些属性,那么抽象类中一定存在构造方法,其存在目的是为了属性的初始化。
    并且子类对象实例化的时候,依然满足先执行父类构造,再执行子类构造的顺序。

    范例如下:

    package com.wz.abstractdemo;
    
    abstract class A{//定义一个抽象类
    	
    	public A(){
    		System.out.println("*****A类构造方法*****");
    	}
    
    	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
    	
    }
    //单继承
    class B extends A{//B类是抽象类的子类,是一个普通类
    
    	public B(){
    		System.out.println("*****B类构造方法*****");
    	}
    	
    	@Override
    	public void print() {//强制要求覆写
    		System.out.println("Hello World !");
    	}
    	
    }
    public class TestDemo {
    
    	public static void main(String[] args) {
    		A a = new B();//向上转型
    	}
    
    }
    
    

    执行结果:

    *****A类构造方法*****
    *****B类构造方法*****
    

    (2)抽象类可以用final声明么?
    不能,因为抽象类必须有子类,而final定义的类不能有子类;

    (3)抽象类能否使用static声明?
    先看一个关于外部抽象类的范例:

    package com.wz.abstractdemo;
    
    static abstract class A{//定义一个抽象类
    	
    	public abstract void print();
    	
    }
    
    class B extends A{
    	
    	public void print(){
    		System.out.println("**********");
    	}
    }
    public class TestDemo {
    
    	public static void main(String[] args) {
    		A a = new B();//向上转型
    		a.print();
    	}
    
    }
    
    

    执行结果

    Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    	Illegal modifier for the class A; only public, abstract & final are permitted
    
    	at com.wz.abstractdemo.A.<init>(TestDemo.java:3)
    	at com.wz.abstractdemo.B.<init>(TestDemo.java:9)
    	at com.wz.abstractdemo.TestDemo.main(TestDemo.java:18)
    
    

    再看一个关于内部抽象类:

    package com.wz.abstractdemo;
    
    abstract class A{//定义一个抽象类
    	
    	static abstract class B{//static定义的内部类属于外部类
    		public abstract void print();
    	}
    	
    }
    
    class C extends A.B{
    	
    	public void print(){
    		System.out.println("**********");
    	}
    }
    public class TestDemo {
    
    	public static void main(String[] args) {
    		A.B ab = new C();//向上转型
    		ab.print();
    	}
    
    }
    
    

    执行结果:

    **********
    

    由此可见,外部抽象类不允许使用static声明,而内部的抽象类运行使用static声明。使用static声明的内部抽象类相当于一个外部抽象类,继承的时候使用“外部类.内部类”的形式表示类名称。

    (4)可以直接调用抽象类中用static声明的方法么?
    任何时候,如果要执行类中的static方法的时候,都可以在没有对象的情况下直接调用,对于抽象类也一样。
    范例如下:

    package com.wz.abstractdemo;
    
    abstract class A{//定义一个抽象类
    	
    	public static void print(){
    		System.out.println("Hello World !");
    	}
    	
    }
    
    public class TestDemo {
    
    	public static void main(String[] args) {
    		A.print();
    	}
    
    }
    
    

    运行结果:

    Hello World !
    
    

    (5)有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略掉外部子类。这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类。
    范例如下:

    package com.wz.abstractdemo;
    
    abstract class A{//定义一个抽象类
    	public abstract void print();
    	
    	private static class B extends A{//内部抽象类子类
    		
    		public void print(){//覆写抽象类的方法
    			System.out.println("Hello World !");
    		}
    	}
    	
    	//这个方法不受实例化对象的控制
    	public static A getInstance(){
    		return new B();
    	}
    	
    }
    
    public class TestDemo {
    
    	public static void main(String[] args) {
    		
    		//此时取得抽象类对象的时候完全不需要知道B类这个子类的存在
    		A a = A.getInstance();
    		a.print();
    	}
    }
    
    

    运行结果:

    Hello World !
    

    四、抽象类的应用——模板设计模式

    例如,现在有三类事物:
    (1)机器人:充电,工作;
    (2)人:吃饭,工作,睡觉;
    (3)猪:进食,睡觉。
    现要求实现一个程序,可以实现三种不同事物的行为。

    先定义一个抽象行为类:

    package com.wz.abstractdemo;
    
    public abstract class Action{
    	
    	public static final int EAT = 1 ;
    	public static final int SLEEP = 3 ;
    	public static final int WORK = 5 ;
    	
    	public abstract void eat();
    	public abstract void sleep();
    	public abstract void work();
    	
    	public void commond(int flags){
    	  switch(flags){
    		case EAT:
    			this.eat();
    			break;
    		case SLEEP:
    			this.sleep();
    			break;
    		case WORK:
    			this.work();
    			break;
    		case EAT + SLEEP:
    			this.eat();
    			this.sleep();
    			break;
    		case SLEEP + WORK:
    			this.sleep();
    			this.work();
    			break;
    		default:
    			break;
    		}
    	}
    }
    
    

    定义一个机器人的类:

    package com.wz.abstractdemo;
    
    public class Robot extends Action{
    
    	@Override
    	public void eat() {
    		System.out.println("机器人充电");
    		
    	}
    
    	@Override
    	public void sleep() {
    		
    	}
    
    	@Override
    	public void work() {
    		System.out.println("机器人工作");
    		
    	}
    	
    }
    
    
    

    定义一个人的类:

    package com.wz.abstractdemo;
    
    public class Human extends Action{
    
    	@Override
    	public void eat() {
    		System.out.println("人吃饭");
    		
    	}
    
    	@Override
    	public void sleep() {
    		System.out.println("人睡觉");
    		
    	}
    
    	@Override
    	public void work() {
    		System.out.println("人工作");
    		
    	}
    	
    }
    

    定义一个猪的类:

    package com.wz.abstractdemo;
    
    public class Pig extends Action{
    
    	@Override
    	public void eat() {
    		System.out.println("猪进食");
    		
    	}
    
    	@Override
    	public void sleep() {
    		System.out.println("猪睡觉");
    		
    	}
    
    	@Override
    	public void work() {
    		
    		
    	}
    	
    }
    
    

    测试主类:

    package com.wz.abstractdemo;
    
    public class AbstractDemo {
    
    	public static void main(String[] args) {
    		
    		fun(new Robot());
    		
    		fun(new Human());
    		
    		fun(new Pig());
    
    	}
    	
    	public static void fun(Action act){
    		act.commond(Action.EAT);
    		act.commond(Action.SLEEP);
    		act.commond(Action.WORK);
    	}
    
    }
    
    

    运行结果:

    机器人充电
    机器人工作
    人吃饭
    人睡觉
    人工作
    猪进食
    猪睡觉
    
    

    所有的子类如果要想正常的完成操作,必须按照指定的方法进行覆写才可以,而这个时候抽象类所起的功能就是一个类定义模板的功能。

    展开全文
  • java提高篇(四)-----抽象类与接口

    万次阅读 多人点赞 2013-10-18 21:04:13
     抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力。他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别。  一、抽象类  我们都...

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。

           抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力。他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别。


          一、抽象类

           我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的。如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类。比如new Animal(),我们都知道这个是产生一个动物Animal对象,但是这个Animal具体长成什么样子我们并不知道,它没有一个具体动物的概念,所以他就是一个抽象类,需要一个具体的动物,如狗、猫来对它进行特定的描述,我们才知道它长成啥样。

          在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。

          同时,抽象类体现了数据抽象的思想,是实现多态的一种机制。它定义了一组抽象的方法,至于这组抽象方法的具体表现形式有派生类来实现。同时抽象类提供了继承的概念,它的出发点就是为了继承,否则它没有存在的任何意义。所以说定义的抽象类一定是用来继承的,同时在一个以抽象类为节点的继承关系等级链中,叶子节点一定是具体的实现类。不知这样理解是否有错!!!高手指点….)

          在使用抽象类时需要注意几点:

             1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。

             2、抽象方法必须由子类来进行重写。

             3、只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。

             4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。

             5、子类中的抽象方法不能与父类的抽象方法同名。

             6、abstract不能与final并列修饰同一个类。

             7、abstract 不能与private、static、final或native并列修饰同一个方法。、

          实例:

          定义一个抽象动物类Animal,提供抽象方法叫cry(),猫、狗都是动物类的子类,由于cry()为抽象方法,所以Cat、Dog必须要实现cry()方法。如下:

    public abstract class Animal {
        public abstract void cry();
    }
    
    public class Cat extends Animal{
    
        @Override
        public void cry() {
            System.out.println("猫叫:喵喵...");
        }
    }
    
    public class Dog extends Animal{
    
        @Override
        public void cry() {
            System.out.println("狗叫:汪汪...");
        }
    
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Animal a1 = new Cat();
            Animal a2 = new Dog();
            
            a1.cry();
            a2.cry();
        }
    }
    
    --------------------------------------------------------------------
    Output:
    猫叫:喵喵...
    狗叫:汪汪...


          创建抽象类和抽象方法非常有用,因为他们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样使用他们.抽象类还是有用的重构器,因为它们使我们可以很容易地将公共方法沿着继承层次结构向上移动。(From:Think in java )


          二、接口

          接口是一种比抽象类更加抽象的“类”。这里给“类”加引号是我找不到更好的词来表示,但是我们要明确一点就是,接口本身就不是类,从我们不能实例化一个接口就可以看出。如new Runnable();肯定是错误的,我们只能new它的实现类。

          接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。同时实现该接口的实现类必须要实现该接口的所有方法,通过使用implements关键字,他表示该类在遵循某个或某组特定的接口,同时也表示着“interface只是它的外貌,但是现在需要声明它是如何工作的”。

          接口是抽象类的延伸,java了保证数据安全是不能多重继承的,也就是说继承只能存在一个父类,但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多重继承的缺陷,但是推荐继承和接口共同使用,因为这样既可以保证数据安全性又可以实现多重继承。

          在使用接口过程中需要注意如下几个问题:

             1、个Interface的方所有法访问权限自动被声明为public。确切的说只能为public,当然你可以显示的声明为protected、private,但是编译会出错!

             2、接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为为public static final。可以通过类命名直接访问:ImplementClass.name。

             3、接口中不存在实现的方法。

             4、实现接口的非抽象类必须要实现该接口的所有方法。抽象类可以不用实现。

             5、不能使用new操作符实例化一个接口,但可以声明一个接口变量,该变量必须引用(refer to)一个实现该接口的类的对象。可以使用 instanceof 检查一个对象是否实现了某个特定的接口。例如:if(anObject instanceof Comparable){}。

             6、在实现多接口的时候一定要避免方法名的重复。


          三、抽象类与接口的区别

          尽管抽象类和接口之间存在较大的相同点,甚至有时候还可以互换,但这样并不能弥补他们之间的差异之处。下面将从语法层次和设计层次两个方面对抽象类和接口进行阐述。

          3.1语法层次

          在语法层次,java语言对于抽象类和接口分别给出了不同的定义。下面已Demo类来说明他们之间的不同之处。

          使用抽象类来实现:

    public abstract class Demo {
        abstract void method1();
        
        
        void method2(){
            //实现
        }
    }

           使用接口来实现

    interface Demo {
        void method1();
        void method2();
    }

           抽象类方式中,抽象类可以拥有任意范围的成员数据,同时也可以拥有自己的非抽象方法,但是接口方式中,它仅能够有静态、不能修改的成员数据(但是我们一般是不会在接口中使用成员数据),同时它所有的方法都必须是抽象的。在某种程度上来说,接口是抽象类的特殊化。

          对子类而言,它只能继承一个抽象类(这是java为了数据安全而考虑的),但是却可以实现多个接口。

          3.2设计层次

          上面只是从语法层次和编程角度来区分它们之间的关系,这些都是低层次的,要真正使用好抽象类和接口,我们就必须要从较高层次来区分了。只有从设计理念的角度才能看出它们的本质所在。一般来说他们存在如下三个不同点:

          1、 抽象层次不同。抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。

          2、 跨域不同。抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类。我们知道象类是从子类中发现公共部分,然后泛化成抽象类,子类继承该父类即可,但是接口不同。实现它的子类可以不存在任何关系,共同之处。例如猫、狗可以抽象成一个动物类抽象类,具备叫的方法。鸟、飞机可以实现飞Fly接口,具备飞的行为,这里我们总不能将鸟、飞机共用一个父类吧!所以说抽象类所体现的是一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is-a" 关系,即父类和派生类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的, 仅仅是实现了接口定义的契约而已。

          3、 设计层次不同。对于抽象类而言,它是自下而上来设计的,我们要先知道子类才能抽象出父类,而接口则不同,它根本就不需要知道子类的存在,只需要定义一个规则即可,至于什么子类、什么时候怎么实现它一概不知。比如我们只有一个猫类在这里,如果你这是就抽象成一个动物类,是不是设计有点儿过度?我们起码要有两个动物类,猫、狗在这里,我们在抽象他们的共同点形成动物抽象类吧!所以说抽象类往往都是通过重构而来的!但是接口就不同,比如说飞,我们根本就不知道会有什么东西来实现这个飞接口,怎么实现也不得而知,我们要做的就是事前定义好飞的行为接口。所以说抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。

          上面纯属个人见解,如有出入、错误之处,望各位指点!!!!)

          为了更好的阐述他们之间的区别,下面将使用一个例子来说明。该例子引自:http://blog.csdn.net/ttgjz/article/details/2960451

          我们有一个Door的抽象概念,它具备两个行为open()和close(),此时我们可以定义通过抽象类和接口来定义这个抽象概念:

          抽象类:

    abstract class Door{
        abstract void open();
        abstract void close();
    }

          接口

    interface Door{
        void open();
        void close();
    }

           至于其他的具体类可以通过使用extends使用抽象类方式定义Door或者Implements使用接口方式定义Door,这里发现两者并没有什么很大的差异。

          但是现在如果我们需要门具有报警的功能,那么该如何实现呢?

          解决方案一:给Door增加一个报警方法:clarm();

    abstract class Door{
        abstract void open();
        abstract void close();
        abstract void alarm();
    }

           或者

    interface Door{
        void open();
        void close();
        void alarm();
    }

           这种方法违反了面向对象设计中的一个核心原则 ISP (Interface Segregation Principle)—见批注,在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方 法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变而改变,反之依然。

          解决方案二

          既然open()、close()和alarm()属于两个不同的概念,那么我们依据ISP原则将它们分开定义在两个代表两个不同概念的抽象类里面,定义的方式有三种:

           1、两个都使用抽象类来定义。

          2、两个都使用接口来定义。

          3、一个使用抽象类定义,一个是用接口定义。

          由于java不支持多继承所以第一种是不可行的。后面两种都是可行的,但是选择何种就反映了你对问题域本质的理解。

          如果选择第二种都是接口来定义,那么就反映了两个问题:1、我们可能没有理解清楚问题域,AlarmDoor在概念本质上到底是门还报警器。2、如果我们对问题域的理解没有问题,比如我们在分析时确定了AlarmDoor在本质上概念是一致的,那么我们在设计时就没有正确的反映出我们的设计意图。因为你使用了两个接口来进行定义,他们概念的定义并不能够反映上述含义。

         第三种,如果我们对问题域的理解是这样的:AlarmDoor本质上Door,但同时它也拥有报警的行为功能,这个时候我们使用第三种方案恰好可以阐述我们的设计意图。AlarmDoor本质是们,所以对于这个概念我们使用抽象类来定义,同时AlarmDoor具备报警功能,说明它能够完成报警概念中定义的行为功能,所以alarm可以使用接口来进行定义。如下:

    abstract class Door{
        abstract void open();
        abstract void close();
    }
    
    interface Alarm{
        void alarm();
    }
    
    class AlarmDoor extends Door implements Alarm{
        void open(){}
        void close(){}
        void alarm(){}
    }

           这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其实抽象类表示的是"is-a"关系,接口表示的是"like-a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。

          批注:

       ISP(Interface Segregation Principle):面向对象的一个核心原则。它表明使用多个专门的接口比使用单一的总接口要好。

       一个类对另外一个类的依赖性应当是建立在最小的接口上的。

       一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

          

          四、总结

          1、 抽象类在java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口。

          2、 在抽象类中可以拥有自己的成员变量和非抽象类方法,但是接口中只能存在静态的不可变的成员数据(不过一般都不在接口中定义成员数据),而且它的所有方法都是抽象的。

          3、抽象类和接口所反映的设计理念是不同的,抽象类所代表的是“is-a”的关系,而接口所代表的是“like-a”的关系。

          抽象类和接口是java语言中两种不同的抽象概念,他们的存在对多态提供了非常好的支持,虽然他们之间存在很大的相似性。但是对于他们的选择往往反应了您对问题域的理解。只有对问题域的本质有良好的理解,才能做出正确、合理的设计。

    巩固基础,提高技术,不惧困难,攀登高峰!!!!!!

    展开全文
  • 抽象类

    万次阅读 多人点赞 2019-01-01 11:55:58
    1,抽象类与抽象方法概念 抽象类用来描述一种类型应该具备的基本特征与功能, 具体如何去完成这些行为由子类通过方法重写来完成,如: 犬科均会吼叫,但属于犬科的狼与狗其吼叫内容不同。所以犬科规定了有吼叫功能,但...
  • 什么是抽象类

    千次阅读 2019-06-02 13:29:26
    第四章 抽象类(入门级,大牛忽略) 4.1 抽象类概述(以下内容可能有点烦 但是通俗易懂 简直舒服) 我们创建一个动物类,并且在这个类中创建动物对象,但是当你提到动物类,你并不知道我说的是什么动物,只有看到了...
  • java抽象类

    千次阅读 2019-05-13 21:39:28
    下面小编给大家讲一个java抽象类,在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类...
  • Java 抽象类

    千次阅读 多人点赞 2019-01-28 09:16:52
    Java 抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类抽象类除了不能实例...
  • Java抽象类

    千次阅读 2018-06-04 15:49:24
    这句话概括了抽象的概念,而在Java中,你可以只给出方法的定义不去实现方法的具体事物,由子类去根据具体需求来具体实现。这种只给出方法定义而不具体实现的方法被称为抽象方法,抽象方法是没有方法体的,在代码的...
  • Java笔试面试-抽象类与接口

    万次阅读 多人点赞 2019-09-15 22:29:50
    抽象类 定义:   在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。简单来说,使用...
  • java 抽象类

    千次阅读 2020-02-07 10:40:58
    1.java抽象类的基本概念 普通类就是完善的功能类,直接生产对象并使用,其中的方法都已经实现完整(带有方法体"{}").抽象类的最大特点包含了抽象方法,抽象方法是只声明(没有方法体)的方法,抽象方法定义时使用abstract...
  • 一、抽象类与普通类 二、抽象类与接口 三、小结 概念 抽象类和具体类是相对的概念。“抽象”是一种存在思想逻辑中的概念,而“具体”是一种可见可触摸的现实对象。简单说,比如“人”比“男人”抽象一点,...
  • java抽象类详解

    2019-04-18 16:04:12
    一、抽象类基本概念 二、抽象类的使用 三、抽象类的相关规定(使用限制) 四、抽象类的应用——模板设计模式 一、抽象类基本概念 含有抽象方法的类就是抽象类。普通类中可以含有构造方法,普通方法,static方法...
  • Java抽象类的作用和使用

    万次阅读 多人点赞 2017-02-12 21:04:16
    转载自Java抽象类的使用 /* 当多个类中出现相同功能,但是功能主体不同, 这是可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体。 抽象:看不懂。 抽象类的特点: 1,抽象方法一定在抽象类中。 2,...
  • Java 抽象类 接口 继承 实现

    千次阅读 2016-07-23 17:21:14
    接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。 抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。...
  • //如果一个类实现接口的部分方法,则该类必须是抽象类;实现接口用implements interface It1 { public abstract void f(); public abstract void g(); } abstract class A implements It1 { public ...
  • JAVA抽象类的定义

    万次阅读 多人点赞 2018-08-25 19:24:40
    抽象类的基本概念 抽象方法,只声明而未实现的方法我们称为抽象方法,所有的抽象方法都需要用abstract关键字声明,包含抽象方法的类也需要使用abstract关键字声明,抽象类和普通类相比,区别在于抽象类带有抽象...
  • Java抽象类使用方法

    千次阅读 2017-12-14 15:16:57
    一、抽象类的基本概念 ...普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中...而抽象类是指在普通类的结构里面增加抽象方法的组成部分。 那么什么叫抽象方法呢?在所有的普通方法上面都会
  • java 抽象类的特点

    千次阅读 2019-04-21 19:59:38
    抽象类 在多态中,父类的方法必须存在,因为多态的必要条件必须存在方法重写 方法的实现毫无意义 提供方向的声明即可,不需要实现,就是抽象方法 抽象类的特点:   1 抽象方法和抽象类使用 abstract 修饰  ...
  • Java抽象类Animal和Cat

    2018-11-09 13:58:31
    Java抽象类概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 抽象类除了不...
  • 抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力。他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别。 一、抽象类 我们都知道在...
  • JAVA抽象类和最终类

    2019-05-27 17:04:27
    抽象类 用abstract关键字修饰的类为抽象类,用abstract修饰一个方法为抽象方法。 含有抽象方法的类必须是抽象类,且抽象类必须被继承,抽象方法必须被重写。 抽象类不能被实例化。 抽象方法只需声明,不需要...
  • Java抽象类用法示例详解

    千次阅读 2016-01-09 18:56:48
    转自Java抽象类用法示例详解 Java抽象类的定:java抽象类体现数据抽象的思想,是实现程序多态性的一种手段。也提到抽象类与抽象方法的限制,下面我们会通过一下java抽象类小示例来给你介绍抽象类的用法。希望对你...
  • 标签: java抽象类概念理解抽象类与接口区别抽象类与普通类区别 2017-05-04 16:26 1029人阅读 评论(0) 收藏 举报  分类: Java(17)  版权声明:本文为博主csdn_aiyang原创文章,未经博主...
  • 设计一个扩展自抽象类GeometriObject的新的Triangle类。绘制Triangle类和GeometricObject类的UML图并实现Triangle类。编写一个测试程序,提示用户输入三角形的三条边、一种颜色以及一个表明该三角形是否填充的布尔值...
  • java抽象类和接口

    千次阅读 2019-05-14 17:34:15
    java抽象类和接口 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 开发工具与关键技术:MyEclipse10 作者:朱海恩 撰写时间: 2019.04.30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...
  • Java抽象类知识整理

    2018-07-21 16:10:10
    Java中,不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的...
  • Java 抽象类和接口

    千次阅读 2019-08-03 17:18:42
    2019-8-3抽象类和接口 1.抽象类 ①一个完整的类,所有方法都有实现(方法体),类可以没有方法class A{ 什么都没有},但是有方法就肯定要有实现 ②一个完整的类才可以被实例化,被new出对象来 ③如果一个类暂时有...
  • 抽象类:包含抽象方法的类称为抽象类。 抽象方法:只声明而未实现的方法称为抽象方法。必须使用abstract关键字声明。 *抽象类和抽象方法都必须使用abstract关键字声明。 *抽象方法只声明,不需要定义。 ...
  • java抽象类和抽象方法

    千次阅读 2019-01-11 19:29:03
    ****2、抽象类和抽象方法的特点****3、抽象类的使用:****4、抽象类和抽象方法的实例:俄罗斯方块** 1、什么时候使用抽象方法? 当多个类有相同的方法,但方法体不一样,这时候就可以抽取出抽象方法。 2、抽象类和...

空空如也

1 2 3 4 5 ... 20
收藏数 1,100,034
精华内容 440,013
关键字:

抽象类