一起学 Java 面向对象(二)

一、方法函数

函数也称为方法,就是定义在类中的具有特定功能的一段独立代码。用于定义功能,提高代码的复用性。

函数的特点
1> 定义函数可以将功能代码进行封装,便于对该功能进行复用;
2> 函数只有被调用才会被执行;
3> 对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写,系统会帮你自动加上;
4> 函数中只能调用函数,不可以在函数内部定义函数。

  修饰符  返回值类型  方法名(参数类型 形式参数1,参数类型 形式参数2,..)
  {
    方法体;
    return 返回值;
  }

//修饰符: 可选,告诉编译器如何调用该方法。定义了该方法的访问类型。
//返回值类型:函数运行后的结果的数据类型
//参数类型:形式参数的数据类型

主函数 main():
1> 保证该类的独立运行;
2> 程序的入口,自动调用;
3> jvm调用。

函数的重载 (overload)

重载的概念:
  在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
重载的特点:
  与返回值类型无关,只看参数列表。
重载的好处:
  方便于阅读,优化了程序设计。Java编译器根据方法签名判断哪个方法应该被调用。

什么时候用重载?

  当定义的功能相同,但参与运算的未知内容不同。

  那么,这时就定义一个函数名称以表示起功能,方便阅读,而通过参数列表的不同来区分多个同名函数。

重载的方法必须拥有不同的参数列表。你不能仅仅依据修饰符或者返回类型的不同来重载方法。

重载示例:
  返回两个整数的和
    int add(int x,int y){return x+y;}
  返回三个整数的和
    int add(int x,int y, int z){return x+y+z;}
  返回两个小数的和
    double add(double x,double y){return x+y;}

// 重载区分, 重载和返回值类型没关系
void show(int a,char b,double c){}

a. void show(int x,char y,double z){}//没有,因为和原函数一样。
b. int show(int a,double c,char b){} //重载,因为参数类型不同。
c. void show(int a,double c,char b){}//重载,因为参数类型不同。

public class functc {
    public static void draw(int row, int col){
        for (int i=0; i<row; i++){
            for (int n=0; n<col; n++){
                System.out.print(‘@‘);
            }
            System.out.println();
        }
    }
    public static void main(String[] args) {
        draw(5, 9);
    }
}

打印一个二维数组

public class funcsj {
    }
    public static void main(String[] args) {
        print99();
    }

    public static void print99(){
        for (int i=1; i<10; i++){
            for (int n=1; n<i+1; n++){
                System.out.print(n+"*"+i+"="+i*n+" ");
            }
            System.out.println();
        }
    }
}

// 结果
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81

打印一个99乘法表

public class funcol {
    public static void main(String[] args) {
        int num = add(5, 8, 9);
        System.out.print(num);    //22
    }
     public static int add(int x,int y){
         return x+y;
     }
     public static int add(int x,int y,int z){
         return add(x,y)+z;
     }
}

函数重载

构造方法

当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值。

通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象。

不管你与否自定义构造方法,所有的类都有构造方法,因为Java自动提供了一个默认构造方法,它把所有成员初始化为0。

一旦你定义了自己的构造方法,默认构造方法就会失效。

public class myfunc {
    int x;
    myfunc(int i){
        x = i;
    }
}

// myfunc.java

public class myfunc {
    int x;
    myfunc(int i){
        x = i;
        System.out.println(x);
    }
}

// MyDemoTest.java

public class MyDemoTest {
    public static void main(String args[]) {
        myfunc t1 = new myfunc(9);
        myfunc t2 = new myfunc(5);
        System.out.println(t1.x + " " + t2.x);
      }
}

// 输出结果
9
5
9 5

构造方法实例

可变参数

JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。

在方法声明中,在指定参数类型后加一个省略号(...) 。

一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。

//typeName... parameterName
public static void My( double... nums){...}

public class myfunc {

    public static void printNum( double... numbers) {
        double result = numbers[0];
        System.out.println("The value index eq 0: " + result);

        for (int i = 1; i <  numbers.length; i++){
            System.out.println("The value is " + numbers[i]);
        }
    }

    public static void main(String args[]) {
      // 调用可变参数的方法
        printNum(1, 2, 9, 5, 8);
        printNum(new double[]{1, 2, 6});
     }

}

// 输出结果
The value index eq 0: 1.0
The value is 2.0
The value is 9.0
The value is 5.0
The value is 8.0
The value index eq 0: 1.0
The value is 2.0
The value is 6.0

可变参数实例

finalize() 方法

Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。

例如,你可以使用 finalize() 来确保一个对象打开的文件被关闭了。

在 finalize() 方法里,你必须指定在对象销毁时候要执行的操作。

finalize() 一般格式是:

protected void finalize()
{
   // 在这里终结代码
}

关键字 protected 是一个限定符,它确保 finalize() 方法不会被该类以外的代码调用。

当然,Java 的内存回收可以由 JVM 来自动完成。如果你手动使用,则可以使用上面的方法。

public class myfunc {
    public static void main(String args[]) {
        Cake c1 = new Cake(1);
        Cake c2 = new Cake(2);
        Cake c3 = new Cake(3);  

        c2 = c3 = null;
        System.gc(); //调用Java垃圾收集器
     }
}

class Cake extends Object {
      private int id;
      public Cake(int id) {
        this.id = id;
        System.out.println("Cake Object " + id + "is created");
      }  

      protected void finalize() throws java.lang.Throwable {
        super.finalize();
        System.out.println("Cake Object " + id + "is disposed");
      }
}

// 输出结果
Cake Object 1is created
Cake Object 2is created
Cake Object 3is created
Cake Object 3is disposed
Cake Object 2is disposed

finalize() 方法实例

二、修饰符类型

public 类:类属变量及方法,包内及包外的任何类均可以访问;
protected 类:类属变量及方法,包内的任何类,及包外的那些继承了此类的子类才能访问;
private 类:类属变量及方法,包内包外的任何类均不能访问;
friendly 类:类属变量及方法不以上这三种修饰符来修饰,那么包内的任何类都可以访问它,而包外的任何类都不能访问它(包括包外继承了此类的子类),因此,这种类、类属变量及方法对包内的其他类是友好的,开放的,而对包外的其他类是关闭的。

类:

访问修饰符 修饰符 class 类名称 extends 父类名称 implement 接口名称
(访问修饰符与修饰符的位置可以互换)
访问修饰符
名称 说明 备注
public 可以被所有类访问(使用) public类必须定义在和类名相同的同名文件中
package 可以被同一个包中的类访问(使用) 默认的访问权限,可以省略此关键字,可以定义在和public类的同一个文件中
修饰符
名称 说明 备注
final 使用此修饰符的类不能够被继承  
abstract 如果要使用abstract类,之前必须首先建一个继承abstract类的新类,新类中实现abstract类中的抽象方法。 类只要有一个abstract方法,类就必须定义为abstract,但abstract类不一定非要保护abstract方法不可

变量:

l         Java中没有全局变量,只有方法变量、实例变量(类中的非静态变量)、类变量(类中的静态变量)。

l         方法中的变量不能够有访问修饰符。所以下面访问修饰符表仅针对于在类中定义的变量。

l         声明实例变量时,如果没有赋初值,将被初始化为null(引用类型)或者0、false(原始类型)。

l         可以通过实例变量初始化器来初始化较复杂的实例变量,实例变量初始化器是一个用{}包含的语句块,在类的构造器被调用时运行,运行于父类构造器之后,构造器之前。

l         类变量(静态变量)也可以通过类变量初始化器来进行初始化,类变量初始化器是一个用static{}包含的语句块,只可能被初始化一次。

访问修饰符
名称 说明 备注
public 可以被任何类访问  
protected
可以被同一包中的所有类访问

可以被所有子类访问

子类没有在同一包中也可以访问
private 只能够被当前类的方法访问  

缺省

无访问修饰符

可以被同一包中的所有类访问 如果子类没有在同一个包中,也不能访
修饰符
名称 说明 备注
static 静态变量(又称为类变量,其它的称为实例变量)
可以被类的所有实例共享。

并不需要创建类的实例就可以访问静态变量

final 常量,值只能够分配一次,不能更改
注意不要使用const,虽然它和C、C++中的const关键字含义一样

可以同static一起使用,避免对类的每个实例维护一个拷贝

transient 告诉编译器,在类对象序列化的时候,此变量不需要持久保存 主要是因为改变量可以通过其它变量来得到,使用它是为了性能的问题
volatile 指出可能有多个线程修改此变量,要求编译器优化以保证对此变量的修改能够被正确的处理  

方法:

访问修饰符 修饰符 返回类型 方法名称(参数列表)throws 违例列表

l         类的构造器方法不能够有修饰符、返回类型和throws子句

l         类的构造器方法被调用时,它首先调用父类的构造器方法,然后运行实例变量和静态变量的初始化器,然后才运行构造器本身。

l         如果构造器方法没有显示的调用一个父类的构造器,那么编译器会自动为它加上一个默认的super(),而如果父类又没有默认的无参数构造器,编译器就会报错。super必须是构造器方法的第一个子句。

l         注意理解private构造器方法的使用技巧。

访问修饰符
名称 说明 备注
public 可以从所有类访问  
protected
可以被同一包中的所有类访问

可以被所有子类访问

子类没有在同一包中也可以访问
private 只能够被当前类的方法访问  

缺省

无访问修饰符

可以被同一包中的所有类访问 如果子类没有在同一个包中,也不能访问
修饰符
名称 说明 备注
static 静态方法(又称为类方法,其它的称为实例方法)
提供不依赖于类实例的服务

并不需要创建类的实例就可以访问静态方法

final 防止任何子类重载该方法
注意不要使用const,虽然它和C、C++中的const关键字含义一样

可以同static一起使用,避免对类的每个实例维护一个拷贝

abstract 抽象方法,类中已声明而没有实现的方法 不能将static方法、final方法或者类的构造器方法声明为abstract
native 用该修饰符定义的方法在类中没有实现,而大多数情况下该方法的实现是用C、C++编写的。 参见Sun的Java Native接口(JNI),JNI提供了运行时加载一个native方法的实现,并将其于一个Java类关联的功能
synchronized 多线程的支持 当一个此方法被调用时,没有其它线程能够调用该方法,其它的synchronized方法也不能调用该方法,直到该方法返回

接口:

访问修饰符 interface 接口名称 extends 接口列表

l         接口不能够定义其声明的方法的任何实现

l         接口中的变量总是需要定义为“public static final 接口名称”,但可以不包含这些修饰符,编译器默认就是这样,显示的包含修饰符主要是为了程序清晰

访问修饰符
名称 说明
public 所有 
无访问修饰符(默认) 同一个包内

三、类的继承

继承的特性:

  • 子类拥有父类非private的属性,方法和构造器。
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。
  • Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。
  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。

关键字

继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

extends关键字

在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

implements关键字

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用

final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:

声明类:
    final class 类名 {//类体}
声明方法:
    修饰符(public,private,void,protected等) final 返回值类型 方法名(){//方法体}

实例变量也可以被定义为final,被定义为final的变量不能被修改。被声明为final的内的方法自动地声明为final,但是实例变量并不是final。

 

构造器

子类不能继承父类的构造器(构造方法或者构造函数),但是父类的构造器带有参数的,则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的当属列表。

如果父类有无参构造器,则在子类的构造器中用super调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。

class Animal {
    private String name;
    private int id;
    public Animal(String myName, int myid) {
        name = myName;
        id = myid;
    }
    public void eat(){
        System.out.println(name+"正在吃");
    }
    public void sleep(){
        System.out.println(name+"正在睡");
    }
    public void introduction() {
        System.out.println("Hello everyone, my cardid is "+ id + ", and my name is " + name + ".");
    }
}

class Bird extends Animal {
    public Bird(String myName, int myid) {
        super(myName, myid);
    }
}

class Dog extends Animal {
    public Dog(String myName, int myid) {
        super(myName, myid);
    }
}

class SuperClass {
      private int n;
      SuperClass(){
        System.out.println("SuperClass()");
      }
      SuperClass(int n) {
        System.out.println("SuperClass(int n)");
        this.n = n;
        System.out.println("SuperClass(int n):"+this.n);
      }
}

class SubClass extends SuperClass{
      private int n;
      SubClass(){
        super(300);
        System.out.println("SuperClass");
      }
      public SubClass(int n){
        super(500);
        System.out.println("SubClass(int n):"+n);
        this.n = n;
        System.out.println("n:"+n+", this.n:"+this.n);
      }
}    

public class AnimalMain {
    public static void main(String[] args){
        Animal Mouseobjone = new Dog("小虎", 9);
        Mouseobjone.eat();    //小虎正在吃
        Mouseobjone.introduction();    //Hello everyone, my cardid is 9, and my name is 小虎.
        Animal Mouseobjtwo = new Dog("贝贝", 5);
        Mouseobjtwo.eat();    //贝贝正在吃
        Mouseobjtwo.introduction();    //Hello everyone, my cardid is 5, and my name is 贝贝.

        SubClass sc = new SubClass();
        //输出
        //SuperClass(int n)
        //SuperClass(int n):300
        //SuperClass
        SubClass sc2 = new SubClass(200);
        //输出
        //SuperClass(int n):500
        //SubClass(int n):200
        //n:200, this.n:200
    }
}

practice

四、重写(Override)与重载(Overload)

方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载是一类中多态性的一种表现。

重写规则:

  • 参数列表必须完全与被重写方法的相同;
  • 返回类型必须完全与被重写方法的返回类型相同;
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为final的方法不能被重写。
  • 声明为static的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个方法,则不能重写这个方法。
  • 当需要在子类中调用父类的被重写方法时,要使用super关键字。

class Animal{
    public void move(){
        System.out.println("动物可以行走");
    }
}

class Dog extends Animal{
    public void move(){
        super.move();
        System.out.println("狗会跳");
    }
    public void bark(){
        System.out.println("狗会叫");
    }
}

public class Override {
    public static void main(String args[]){
        Animal animalobj = new Animal();
        Dog dogobj = new Dog();

        animalobj.move();
        dogobj.move();
        //dogobj.bark();    //会报错!!!抛出一个编译错误,因为dogobj的引用类型Animal没有bark方法。
    }
}

practice

重载(overloading)

是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

只能重载构造函数

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

public class Overloading {
    public int test(){
        System.out.println("This is one.");
        return 1;
    }

    public void test(int a){
        System.out.println("This is two.");
    }

    public String test(int a,String s) {
        System.out.println("This is three.");
        return "3";
    }

    public static void main(String args[]) {
        Overloading olobj = new Overloading();
        System.out.println(olobj.test());    //This is one.、1
        olobj.test(1);    //This is two.
        System.out.println(olobj.test(1, "test3"));    //This is three.、3
    }
}

practice

五、多态

多态的优点

  • 1. 消除类型之间的耦合关系
  • 2. 可替换性
  • 3. 可扩充性
  • 4. 接口性
  • 5. 灵活性
  • 6. 简化性

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理

public class Polymorphism {
    public static void main(String[] args) {
        show(new Cat());  // 以 Cat 对象调用 show 方法
        show(new Dogo());  // 以 Dogo 对象调用 show 方法

        Animalo a = new Cat();  // 向上找方法
        a.eat();               // 调用的是 Cat 的 eat
        Cat c = (Cat)a;        // 向下找方法
        c.work();        // 调用的是 Cat 的 catchMouse
    }

    public static void show(Animalo a)  {
        a.eat();
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情
            Cat c = (Cat)a;
            c.work();
        } else if (a instanceof Dogo) { // 狗做的事情
            Dogo c = (Dogo)a;
            c.work();
        }
    }
}

abstract class Animalo {
    abstract void eat();
}  

class Cat extends Animalo {
    public void eat() {
        System.out.println("吃鱼");
    }
    public void work() {
        System.out.println("抓老鼠");
    }
}  

class Dogo extends Animalo {
    public void eat() {
        System.out.println("吃骨头");
    }
    public void work() {
        System.out.println("看家");
    }
}

practice

六、抽象类

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

声明抽象方法会造成以下两个结果:

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

抽象类规定1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

  • 2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  • 4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
  • 5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

abstract class Employeem {
    private String name;
    private String address;
    private int number;

    public abstract double macPany();
}

class Salary extends Employeem{
    private double salary=1;
    public double macPany(){
        System.out.println("Welcome to macPany.");
        return salary;
    }
}

public class Employee {
    public static void main(String[] args){
        Salary macPanyobj = new Salary();
        macPanyobj.macPany();
    }
}

practice

七、封装

在面向对象程式设计方法中,封装(Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

封装的优点

  • 1. 良好的封装能够减少耦合。
  • 2. 类内部的结构可以自由修改。
  • 3. 可以对成员变量进行更精确的控制。
  • 4. 隐藏信息,实现细节,一般限制为private。

public class EncapBase {
    public static void main(String[] args){
        EncapTmp encaptmpobj = new EncapTmp();
        System.out.println(encaptmpobj.getName());    //null
        encaptmpobj.setName("nick");
        System.out.println(encaptmpobj.getName());    //nick
    }
}

class EncapTmp{

    private String name;
    private int age;

    public String getName(){
        return name;
    }

    public int getAge(){
        return this.age;
    }

    public void setName(String namenew){
        name = namenew;
    }

    public void setAge(int age){
        this.age = age;
    }
}

practice

八、接口

接口(Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

  • 一个接口可以有多个方法。
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多重继承。

接口特性

  • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
  • 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误。
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键子。
  • 接口中的方法都是公有的。

抽象类和接口的区别

  • 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  • 接口中不能还有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

接口的声明语法格式如下:

[可见度] interface 接口名称 [extends 其他的类名] {
        // 声明变量
        // 抽象方法
}

接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

实现一个接口的语法,可以使用这个公式:

...class...implements 接口名称[, 其他接口, 其他接口..., ...] ...

// Animal.java
interface Animal {
    public void eat();
    public void travel();
}

// Dog.java
public interface Dog extends Animal {
    public void FallInLove();
    public void HomePolice();
}

// Pig.java
public interface Pig {
    public void BigEat();
    public void Sleep();
}

// Sheep.java
public interface Sheep extends Animal, Pig {

}

单继承与多继承

// Animal.java
interface Animal {
    public void eat();
    public void travel();
}

// MammalInt.java
public class MammalInt implements Animal {

    public void eat(){
        System.out.println("Animal eat..");
    }

    public void travel(){
        System.out.println("Animal travel..");
    }

    public static void main(String args[]){
        MammalInt mobj = new MammalInt();
        mobj.eat();    //Animal eat..
        mobj.travel();    //Animal travel..
    }

}

practice

九、包(package)

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

包的作用

  • 1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
  • 2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
  • 3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

package pkg1[.pkg2[.pkg3…]];

例如,一个Something.java 文件它的内容:
package net.java.util
public class Something{
   ...
}
# 它的路径应该是 net/java/util/Something.java 这样保存的

包申明

包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。

如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

包导入

payroll 包名
Employee 类名

payroll.Employee    # 全名导入
import payroll.*;
import payroll.Employee;
时间: 2024-11-02 11:32:07

一起学 Java 面向对象(二)的相关文章

菜鸟学Java(二十)——你知道long和Long有什么区别吗?

Java中数据类型分两种: 1.基本类型:long,int,byte,float,double2.对象类型:Long,Integer,Byte,Float,Double其它一切java提供的,或者你自己创建的类. 其中Long叫 long的包装类.Integer.Byte和Float也类似,一般包装类的名字首写是数值名的大写开头. 什么是包装类? 在java中有时候的运算必须是两个类对象之间进行的,不充许对象与数字之间进行运算.所以需要有一个对象,这个对象把数字进行了一下包装,这样这个对象就可以

菜鸟学Java(二十一)——如何更好的进行单元测试——JUnit

测试在软件声明周期中的重要性,不用我多说想必大家也都非常清楚.软件测试有很多分类,从测试的方法上可分为:黑盒测试.白盒测试.静态测试.动态测试等:从软件开发的过程分为:单元测试.集成测试.确认测试.验收.回归等. 在众多的分类中,与开发人员关系最紧密的莫过于单元测试了.像其他种类的测试基本上都是由专门的测试人员来完成,只有单元测试是完全由开发人员来完成的.那么今天我们就来说说什么是单元测试,为什么要进行单元测试,以及如更好的何进行单元测试. 什么是单元测试? 单元测试(unit testing)

从零开始学java(二)类与对象

面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为. 类是对象的抽象,对象是类的具体实例. 1.构造一个类,让其拥有属性和方法 public class Employee { //属性,私有化属性,并提供方法让其能够通过方法访问 private String name; private int age; private double salary; private static final int NUMBER=217;

java 面向对象二

基本数据类型的相等判断 基本数据类型使用"=="来进行判断 如: [java] view plaincopyprint? int in1 = 22; int in2 = 22; System.out.println(in1 == int2);//输出true String类的相等判断 [java] view plaincopyprint? String str1 = "Lixing Hua"; String str2 = new String("Lixin

从零开始学java (面向对象)

面对对象 简单理解面向对象 面对对象我们首先要知道什么是什么对象(不是处对象哦),对象是一个具体的实体,例如:某一个人就是一个对象,他有具体的属性,他有一个大鼻子或者是小鼻子,他长的帅或者不帅,而他具有的特征就是他自身的属性,而他却属于人这个类里的一个实例. 面向对象的思想 作为面向对象的思维来说,当你拿到一个问题时,你分析这个问题不再是第一步先做什么,第二步再做什么,这是面向过程的思维,你应该分析这个问题里面有哪些类和对象,这是第一点,然后再分析这些类和对象应该具有哪些属性和方法.这是第二点.

菜鸟学Java(二十二)——又一次认识泛型

泛型是Java SE 1.5的新特性,泛型的本质是參数化类型,也就是说所操作的数据类型被指定为一个參数.这样的參数类型能够用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的优点是安全简单. 规则和限制 1.泛型的类型參数仅仅能是类类型(包含自己定义类),不能是简单类型.2.同一种泛型能够相应多个版本号(由于參数类型是不确定的),不同版本号的泛型类实例是不兼容的.3.泛型的类型參数能够有多个.4.泛型的參数类型能够使用extends语句,比如<T extend

菜鸟学Java(二十二)——重新认识泛型

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的好处是安全简单. 规则和限制 1.泛型的类型参数只能是类类型(包括自定义类),不能是简单类型.2.同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的.3.泛型的类型参数可以有多个.4.泛型的参数类型可以使用extends语句,例如<T extends sup

跟我学Java反射——二步曲

上一篇文章我们已经将反射的基本知识和class类以及类的加载器进行了介绍,在上一篇我们还学习了四种得到Class类对象的方式,但是有了class对象我们能做些什么呢,学习完这篇文章,就可以得到答案了. 获取类的完整结构 这篇文章我们主要通过demo来学习,我先将demo需要用到的代码进行简单介绍. 一个接口MyInterface代码: package com.tgb.reflect.common; import java.io.Serializable; public interface MyI

重学JAVA基础(二):Java反射

看一下百度的解释: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息    以及动态调用对象的方法的功能称为java语言的反射机制. 先看一下一个例子: 这是最简单的反射使用方法,通过反射来调用类的方法. 下面通过一个需求来做反射实验:有3种人类(黄,白,黑),分别继承于Human类,都有人类的共同操作Behaviour /** * 行为,区别于动物 * @author tomsnail *