Java教程

抽象和接口

本文主要是介绍抽象和接口,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1、final定义

    final关键字有最终的,不可修改的含义

    final使用场合

        final 用于声明属性,方法和类

        1)属性:定义就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改。

        2)方法:定义必须有实现代码,并且子类里不可被覆盖。

        3)类:不能被定义为抽象类或是接口,不可被继承。

2、final修饰属性

    如果某个变量被final修饰,那么该变量就成为常量,不能被修改,一般语法:

    语法:权限修饰符 final 数据类型 常量名 = 值;

    常量在声明时必须初始化,声明之后不能对其进行二次赋值,其后任何试图对常量进行赋值的语句都将报错。

    赋值两种方式:构造方法赋值和声明时等号赋值

   final属性赋值

   1)final与static一起使用,声明方式有2种

     1.在声明时同时赋值:private static final int age=20;

     2.在声明时不赋值,在静态代码块赋值

        private static final int age;

        static{

           age=21;

        }

   2)final不与static一起使用,声明方式有2种:

     1.在声明时同时赋值:private final int age=20;

     2.在声明时不赋值,在初始化代码块或者构造方法赋值

               private static final int age;

               {

                  age=21;

               }

               或者:

               public TestFinal() {

                  age=21;

               }

 

  总的原则:保证创建每一个对象的时候,final属性的值是确定的

  对参数做final修饰

  在方法参数前面加final关键字,为了防止数据在方法体中被修改。

     public void  m1(final  int a){

            a=3;

        }

 

3、final修饰方法

    如果将某个成员方法修饰为final,则意味着该方法不能被子类覆盖,这就和抽象方法必须由子类实现的规定互相矛盾,因此,final和abstract不能同时修饰一个方法

    final方法的一般声明格式是:

    [访问权限] final 返回值类型 方法名(参数列表) {

                  ……

    }

    例子:

    public class Animal {

        public final void eat(){

            System.out.println("动物在吃饭");

        }

    }

    public class Dog extends Animal {

        @Override//Error:(3, 17) java: Dog中的eat()无法覆盖Animal中的eat()

                     被覆盖的方法为final

        public void eat() {

            System.out.println("狗在啃骨头");

        }

    }

 

4、final修饰类

如果将某个类修饰为final,则说明该类无法被继承,一般语法

    [访问权限] final class 类名 {

                  成员列表

           }

    案例:

    public final class Animal {

        public  void eat(){

            System.out.println("动物在吃饭");

        }

    }

    public class Dog extends Animal {//Error:(1, 26) java: 无法从最终Animal进行继承

        @Override

        public void eat() {

            System.out.println("狗在啃骨头");

        }

    }

 

5、静态的定义

如果类的某个属性,不管创建多少个对象,属性的存储空间只有唯一的一个,那么这个属性就应该用static修饰,被static修饰的属性被称为静态属性,被static修饰的方法被称为静态方法。

static属性可以使用对象.属性名调用,也可以直接用类名.属性名调用。

 

6、静态成员变量

被static修饰的成员变量被称为静态成员变量或者是静态属性

静态属性是类的所有对象共享的,即不管创建了多少个对象,静态属性在内存中只有一个

案例:

package T02静态;

 

public class Employee {

    String name; //对象变量或者实例变量,有几个对象在内存就有几份

    double salary;

    static int count;//属于类的变量,为所有该类的对象共享,在内存中只有一份

 

    public Employee() {

    }

 

    public Employee(String name, double salary) {

        this.name = name;

        this.salary = salary;

        count++;

    }

}

 

package T02静态;

 

public class TestEmployee {

    public static void main(String[] args) {

        //创建两个对象

        Employee employee1 = new Employee("冯凯伦", 5000);

        employee1.count=10;

        Employee employee2 = new Employee("开赛尔", 8000);

        System.out.println(employee1.name+"的工资是:"+employee1.salary+",count="+employee1.count);//count=11

        System.out.println(employee2.name+"的工资是:"+employee2.salary+",count="+Employee.count);//count=11

    }

}

 

7、静态方法

被static修饰的方法称为静态方法,不与某个特定的对象关联

权限修饰符 static 返回值类型 方法名(){}

调用方式:

1)对象名.方法名(实参列表);

2)类名.方法名(实参列表);

public class TestEmployee {

    public static void main(String[] args) {

        //创建两个对象

        Employee employee1 = new Employee("冯凯伦", 5000);

        employee1.count=10;

        Employee employee2 = new Employee("开赛尔", 8000);

//        employee1.show();

        Employee.show();

    }

}

总结

本类的方法之间的调用

静态方法可以被任何方法(静态方法和非静态方法)直接调用;

非静态方法可以被非静态方法直接调用;

非静态方法不能被静态方法直接调用,需要创建对象,用对象名调用。

不用类方法之间的调用

调用静态方法,使用类名直接调用 ;

非静态方法不能直接调用,需要创建对象,用对象名调用。

 

8、静态代码块

static代码块

随着类的加载而加载,只执行一次

用于给类进行初始化

实例化代码块

    实例化代码块给对象初始化,在构造方法前执行

static代码块和实例化代码块同时出现时优先级

    静态代码块>实例化代码块>构造方法

    案例:验证代码块的执行顺序

    package T04static代码块;

 

    public class A {

        static {

            System.out.println("static代码块");

        }

        {

            System.out.println("实例化代码块");

        }

 

        public A() {

            System.out.println("构造方法");

        }

    }

    package T04static代码块;

 

    public class TestCopyRecursive {

        public static void main(String[] args) {

            A a = new A();

        }

    }

 

9、static import机制

JDK1.5中引入了“Static Import”机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员

使用方法:

1.导入方法:import static 包名.类名.静态方法名

2.调用方法:方法名(实参列表)

案例:

package T04static代码块;

 

import static java.lang.Math.abs;

 

public class B {

    public static void main(String[] args) {

        int abs = abs(-20);

        System.out.println("abs = " + abs);

    }

}

=================

1、抽象的概念与定义

什么时候使用抽象?当描述一个类的时候,如果一个类不应该有对象,那么该类就可以定义为抽象类,

如果不能确定功能方法如何定义,功能方法应该描述为抽象方法

抽象类的概念:   如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类

抽象类的定义语法: public abstract class 类名{类体}

抽象方法的定义语法:public abstract 返回值类型 方法名(形参列表);

2、抽象类的特点

抽象类不可以被实例化,也就是不可以用new创建对象 ,但有构造方法,主要用于实例化子类调用抽象类构造方法初始化成员变量。

用abstract修饰的类就是抽象类。抽象方法必须定义在抽象类中。但是抽象类中不一定有抽象方法。

方法只有声明没有实现时,该方法就是抽象方法,需要用abstract来修饰,抽象方法必须定义在抽象类中,该类也必须被abstract来修饰。

抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。

抽象类可以有成员属性和非抽象的成员方法。

案例:

package T05抽象类;

 

public abstract class Shape {

    int n;

    public Shape() {

        System.out.println("Shape.Shape()构造方法");

    }

 

    public Shape(int n) {

        System.out.println("Shape.Shape(int n)构造方法");

        this.n = n;

    }

 

    public abstract double area();

    public double girth(){

        return 0;

    }

}

package T05抽象类;

 

public class Rect extends Shape {

    public Rect() {

        super();

        System.out.println("Rect.Rect()构造方法");

    }

 

    public Rect(int n) {

        super(n);

    }

 

    @Override

    public double area() {

        return 0;

    }

}

package T05抽象类;

 

public class TestCopyRecursive {

    public static void main(String[] args) {

        Rect rect = new Rect(10);

 

    }

}

 

抽象类可以没有抽象方法。

抽象类可以继承普通类与抽象类。

抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化。

abstract与其他修饰符的关系:

       final与abstract不能共存:

              final:它的作用  修饰类代表不可以继承  修饰方法不可重写

              abstract修饰类就是用来被继承的,修饰方法就是用来被重写的。

       static static修饰的方法可以用类名调用,对于abstract修饰的方法没有具体的方法实现,所以不能直接调用,也就是说不可以与static共存。

       private  private修饰的只能在本类中使用,abstract方法是用来被子类进行重写的,有矛盾所有不能共存.

3、抽象类与普通类的异同

1)相同点

访抽象类和普通类都是用来描述事物的,都在内部定义了成员。

2)不同点

  普通类有足够信息来描述事物,抽身象类描述事物的信息有可能不够充足

  普通类不能定义抽象方法,只能定义普通方法,抽象类中可以定义抽象方法,同时也可以定义普通方法

  普通类可以被实例化,抽象类不可以被实例化

 

 

5、接口的概念

java接口是一系列方法的声明,是一些抽象的集合,一个接口只有抽象方法没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

简单地说,接口就是特殊的抽象类,即所有方法都是抽象方法的抽象类就是Java中的接口(interface)

一句话:接口就是一堆抽象方法的集合

6、定义接口的格式

[修饰符]   interface   接口名{

       [public] [static] [final] 数据类型 变量名;  //接口中的成员变量就是常量

       [public] [abstract] 方法( );/“?b

}

接口中的成员修饰符是固定的:

public static final 修饰的变量变常量,该值不能改变,只能读

修饰符:可选,用于指定接口的访问权限,可选值为public。即使省略,也依然是public。

接口名:必选参数,用于指定接口的名称,接口名必须是合法的Java标识符。一般情况下,要求首字母大写

方法:接口中的方法只有定义而没有被实现。

package T08接口;

 

public interface A {

    public static final double PI=3.14159265;

    void m1();

}

 

7、类与接口的关系

[访问权限修饰符] class 类名 [extends 父类名] [implements 接口列表]{

 

     必须重写接口中的方法( ){ }

 

   }

   实现一个接口

package T08接口;

 

public interface A {

    public static final double PI=3.14159265;

    void m1();

}

package T08接口;

 

public class AdeImpl implements A {

    @Override

    public void m1() {

        System.out.println("AdeImpl.m1()方法");

    }

}

package T08接口;

 

public class TestCopyRecursive {

    public static void main(String[] args) {

        AdeImpl ade = new AdeImpl();

        ade.m1();

    }

}

类与接口之间是实现关系,类实现接口。

接口不可以被实例化

实现了接口的实现类必须重写接口中所有抽象方法后,这个子类才可以被实例化,否则报错。

一个类可以实现多个接口,多个接口用逗号分隔,也可以不实现接口。

Java不支持多继承,Java将多继承机制进行改良变成了多实现

一个类在继承另一个类同时,还可以实现多个接口

接口的出现避免了单继承的局限性

package T08接口;

 

public class AbcdeImpl extends D implements A,B,C {

 

    @Override

    public void m1() {

        System.out.println("AbcdeImpl.m1");

    }

 

    @Override

    public void m2() {

        System.out.println("AbcdeImpl.m2");

    }

 

    @Override

    public void m3() {

        System.out.println("AbcdeImpl.m3");

    }

 

    @Override

    public void m4() {

        System.out.println("AbcdeImpl.m4");

    }

}

 

 8、接口和接口的关系

    1.接口与接口之间是继承关系,而且可以多继承

    2.语法:

        [修饰符]   interface 接口名 extends 接口名,接口名{接口中的方法( ){}}

    3.接口的出现避免了单继承的局限性

9、接口与抽象类的区别

在Java中接口是一个比抽象类更加抽象的概念,由于只声明行为,因此在接口中的方法均是抽象的,下表中罗列了接口和抽象类的差异:

 

  抽象类体现继承关系,一个类只能单继承接口体现实现关系,一个类可以多实现
  抽象类是继承is a关系(所属关系)在定义该体系的基本共性内容接口是实现是like a关系(不所属关系)在定义该体系额外功能

10、接口可实现多继承原因  接口继承与类继承对比:

   Java类的继承是单一继承,Java接口的继承是多重继承接口可实现多继承原因分析:
   不允许类多重继承的主要原因是,如果A同时继承B和C,而B和C同时有一个D方法,A无法确定该继承那一个
   接口全都是抽象方法,不存在实现冲突,继承谁都可以,所以接口可继承多个接口

11、JDK8接口的默认方法

  Java8之前,Java接口纯粹是契约的集合,是一种程序设计的表达方式。从数据抽象的角度看,能够在不定义class的同时又可以定义type,是程
  序设计中强大而有用的机制。Java姜口就定这当纯竿日女H上PX日o人白象
  Java8之前,接口不能升级。因为在接口中添加一个方法,会导致老版本接口的所有实现类的中断

    Java8之后,lambda表达式作为核心出现,为了配合lambda表达式,JDK中Collection库需要添加新的方法,如forEach(), stream()等,于是引入了默认方法(defender    methods,Virtual  extension metthods)。

  默认方法是库/框架设计者的后悔药。对于以前的遗留代码,大家都不知
  道有这个新方法,既不会调用,也不会去实现,如同不存在;编写新代码的程序员可以将它视为保底的方法体。类型层次中任何符合override规则
  的方法,优先于默认方法,因为遗留代码可能正好有同样的方法存在

 

默认方法理论上抹杀了Java接口与抽象类的本质区别-前者是行为契约的集合,后者是接口与实现的结合体。当然,语法上两者的差别和以前一样。这就需要我们来自觉维护两者的本质区别,把默认方法作为库、框架向前兼容的手段

 

12、面向接口编程

 三层架构Ul展示层业务层数据层

使用三层架构编写图书商城

⑴)登录功能
(⑵)修改密码

大总结:

1.final 最终,不可变

    1.类:不能别继承

    2.方法:不能被重写

    3.变量:常量

2.static 静态的 类的 共享的

    1.类变量 对象共享

    2.类方法,

3.抽象类:abstract

4.接口:interface

这篇关于抽象和接口的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!