Java入门——(3)面对对象(下)

关键词:  类的继承、final关键字、多态、接口、异常、包、访问控制
1、类的继承
      一、类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称做子类,现有类被称做父类,子类会自动拥有父类全部可继承的属性和方法,使用 extends关键字。
 
class A{}
class B extends A{}

 

       在Java中继承的体现:
       ①Java容许单继承。不直接支持多继承,将多继承进行其余方式的体现。
       ②单继承:一个子类只能有一个父类。
class A{}
class B{}
class C extends A,B{}  //C类不能够同时继承A类和B类
       ③多继承:一个子类能够有多个父类,用多实现体现。
       ④多重继承,继承体系。
       学习继承体系时,应该参阅顶层的类中的内容,了解这个体系的基本功能。使用这个体系功能,须要建立最子类的对象。(看顶层,建底层。)
 
      二、override:子父类中的定义了如出一辙的函数。运行的结果:子类的函数在运行。这种状况在子父类中,是函数的另外一个特性:override(重写、覆盖、复写)。
      重写的注意事项:

      ①子类覆盖父类,必须保证权限要大于或等于父类的权限。html

      ②静态覆盖静态。java

      ③写法上必须如出一辙,函数的返回值类型 函数名 参数列表都要同样。编程

       三、super关键字网络

       ①子父类中构造函数的特色:
       当子父类都有构造函数时,先执行父类的构造函数,再执行子类的构造函数,由于子类的全部的构造函数中的第一行都有一句隐式语句
       super();//默认调用的是父类中的空参数的构造函数。
 
       为何子类中的构造函数有一句隐式的super()?
       缘由:子类会继承父类中的内容,因此子类在初始化时,必须先到父类中去执行父类的初始化动做。才能够更方便使用父类中的内容。
       当父类中没有空参数构造函数时,子类的构造函数必须同构显式的super语句指定要访问父类中的构造函数。
       细节:

①若是子类的构造函数第一行写了this调用了背离其余构造函数,那么super调用父类的语句是没有的,由于this()或者super(),只能在构造函数的第一行,由于初始化动做要先执行。jvm

②父类构造函数中是否有隐式的super呢?也是有的,只要是构造函数默认第一行都是super();ide

父类的父类是谁?super调用的究竟是谁的构造函数,在Java体系在设计,定义了一个全部对象的父类object。
总结:类中的构造函数默认第一行都有隐式的super()语句,在访问父类中的构造函数。
因此父类的构造函数既能够给本身对象初始化,也能够给本身的子类对象初始化。
若是默认的隐式super的语句没有对应的构造函数,必须在构造函数中经过this后者super的形式明确调用的构造函数。
 
super应用:
①子类的实例化过程的应用,也是super调用的应用。

②只要使用父类的指定初始化动做,就在子类中经过super(参数列表)格式进行调用。函数

super关键字的用法:

①使用super关键字调用父类的成员变量和成员方法。具体格式:工具

super.成员变量
super.成员方法([参数1,参数2……….])

②使用super关键字调用父类的构造方法,具体格式:post

super([参数1,参数2……….])
经过super调用父类构造方法的代码必须位于子类构造方法的第一行,且只能出现一次。
      在定义一个类时,若是没有特殊需求,尽可能在类中定义一个无参的构造方法,避免继承时出现错误。
 
      继承的弊端:打破封装性。
 
2、final关键字
 
      一、final(最终化)修饰符,能够修饰类、方法、变量(成员变量、局部变量、静态变量)。

      ①final修饰的类是一个最终类,该类将不能被继承,不能派生子类。学习

      ②final 修饰的方法是最终方法,不能够重写。
      当父类中定义某个方法时,若是不但愿被子类重写,就可使用final关键字修饰该方法。
      如:public final void shout(){}

③final修饰的变量是一个常量,只能被赋值一个。

 如:final int num = 2;

二、【何时会在程序中定义final常量呢?】
当程序中一个数据使用时是固定不变的,这时为了增长阅读性,能够给该数据起个名字。
这是变量,为了保证这个变量的值不被修改,加上final修饰,这是一个阅读性很强的常量。
书写规范,被final修饰的常量名全部字母都是大写的。若是由多个单词间经过 _ 链接。
 
3、抽象类和接口
一、abstract(抽象)
抽象类:在描述事物时,没有足够的信息描述一个事物,这时该事物就是抽象事物。
定义了抽象函数的类,也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。
抽象方法的类必须声明为抽象类,但抽象类能够不包含任何抽象方法,只要abstract关键字修饰便可。
 
【抽象类的特色】

        ①抽象类和抽象方法都须要被abstract修饰。(抽象方法必定要定义在抽象类中)。

//定义抽象类Animal
abstract class Animal{
//定义抽象方法shuot()
abstract int shout ();
}

       ②抽象类不能够建立实例,缘由:调用抽象方法没有方法体。

       ③只要覆盖了抽象类中全部的抽象方法后,其子类才能够实例化。不然该子类仍是一个抽象类。

       之因此继承,更多的是在思想,是面对共性类型操做会更简单。
 
    二、接口(interface)
    接口:若是一个类中的全部抽象方法都是抽象的,则能够将这个类用另一种方式来定义,即接口。在定义接口时,须要使用interface关键字来声明,如:
1 interface Animal{
2     int ID = 1; //定义全局变量
3     void breathe(); //定义抽象方法
4     void run ();
5 } // Animal 即为一个接口,接口中定义的的方法和变量都包含一些默认修饰符“public abstract”(抽象方法)“public static final”(全局变量)。
 
      接口的特色:

①接口能够建立对象;

②子类必须覆盖掉接口中全部的抽象方法后,子类才能够实例化。不然子类是一个抽象类。

③实现多接口示例:

复制代码
interface Run{
程序代码…..
}
interface Fly{
程序代码…..
}
class Bird implements Run,Fly{
程序代码…….
}
复制代码
       定义子类去覆盖接口的方法:子类必须和接口产生关系,类与类的关系是继承,类与接口之间的关系是实现,经过关键字implements 。
 
接口最重要的体现:解决多继承的弊端。将多继承这种机制在Java中经过多实现完成。
多继承的弊端:当多个父类中有相同功能时,子类调用会产生不肯定性。
其核心缘由就是在于多继承父类中功能有主体,而致使调用运行时,不肯定运行哪一个主体内容。
接口中的功能都没有方法体,由子类来明确。
 
       若是子类想要继承扩展其余类中的功能,可经过接口实现:
class Dog extends Canidae implements Animal{ //先继承,再实现
程序代码……
}
       父类定义事物的基本功能,接口定义事物的扩展功能。
 
       接口出现后的一些细节:类与类之间是继承关系,类与接口是实现关系;接口与接口之间是继承关系,并且能够多继承。
 
4、多态
一、多态的概述
【体现】
父类的引用或者接口的引用指向了本身的子类对象。
Dog d = new Dog(); // Dog对象的类型是Dog类型
Animal a = new Dog(); // Dog对象的类型右边是Dog类型,左边Animal 类型。
【好处】
提升了程序的扩展性。
【弊端】
经过父类引用操做子类对象时,只能使用父类中已有的方法,不能操做子类特有的方法。
【前提】
①必须有关系,继承、实现。
②一般都有重写操做。
复制代码
 1 //定义接口Animal
 2 interface Animal{
 3     void shout();
 4 }
 5 //定义Cat类实现Animal接口
 6 class Cat implements Animal{
 7        //实现shout()方法
 8     public void shout(){
 9         System.out.println("喵喵...");
10     }
11 }
12 //定义Dog类型实现Animal接口
13 class Dog implements Animal{
14     public void shout(){
15         System.out.println("汪汪");
16     }
17 }
18 //定义测试类
19 public class Example13 {
20     public static void main(String[] args) {
21         Animal an1 =new Cat();//建立Cat对象,使用Animal类型的变量an1引用
22         Animal an2 =new Dog();//建立Dog对象,使用Animal类型的变量an2引用
23         animalShout(an1);     //调用animalShout()方法,将an1做为参数传入
24         animalShout(an2);     //调用animalShout()方法,将an2做为参数传入
25     }
26     public static void animalShout(Animal an) {
27         an.shout();
28     }
29 }
复制代码

运行结果

喵喵…
汪汪
【子类的特有方法如何调用?】
Animal a = new Dog();//Animal是父类型,new Dog()子对象。
可是父类型引用指向子类对象时,这就是让子类对象进行了类型的提高(向上转型)。
向上转型好处:提升了扩展性,隐藏了子类型。
弊端:不能使用子类型的特有方法。
若是想使用子类的特有方法,只有子类型能够用。
能够向下转型,强制转换。
Animal a = new Dog();
a.eat();
Dog d = (Dog)a; //将a转型为Dog 类型。向下转型。
d.lookHome();
向下转型何时用?当须要使用子类型的特有内容时。
注意:不管向上仍是向下转型,最终都是子类对象作着类型的变化。
【向下转型的注意事项】
Animal a = new Dog();
Cat c = (Cat)a;//向下转型由于不明确具体子类对象类型,因此容易引起classCastException(转型异常)异常。
因此为了不这个问题,须要在向下转型前,作类型的判断。
判断类型用的是关键字 instanceof
复制代码
if(a instanceof Cat){   //a指向的对象的类型是Cat类型。
    //将a转型Cat 类型。
    Cat c = (Cat)a;
    c.catchMouse();
}else if(a instanceof Dog){
    Dog d = (Dog) a;
    d.lookHome();
}
复制代码
示例:
复制代码
 1 interface Animal{
 2     void shout();//定义抽象方法shout()
 3 }
 4 //定义Cat类实现Animal接口
 5 class Cat implements Animal{
 6     //实现抽象方法shout()
 7     public void shout(){
 8         System.out.println("喵喵...");
 9     }
10     //定义sleep()方法
11     public void sleep(){
12         System.out.println("猫在睡觉.....");
13     }
14 }
15 //定义Dog类实现Animal接口
16 class Dog implements Animal{
17     //实现抽象方法shout()
18     public void shout(){
19         System.out.println("汪汪...");
20     }
21 }
22 //定义测试类
23 public class Example14 {
24     public static void main(String[] args) {
25         Animal dog = new Dog();    //建立Dog类的实例对象
26         animalShout(dog);    //调用animalShout()方法,将dog做为参数传入
27     }
28     public static void animalShout(Animal animal) {
29         if (animal instanceof Cat) {
30             Cat cat = (Cat) animal;//将animal对象强制装换为Cat类型
31             cat.shout();           //调用cat的shout()方法
32             cat.sleep();           //调用cat的sleep()方法
33         }else{
34             System.out.println("this animal is not a cat!");
35         }
36     }
37 }
复制代码

 运行结果:

this animal is not a cat!
【转型总结】

①何时向上转型?

提升程序的扩展性,不关系子类类型(子类型被隐藏)。
须要用子类的特有方法吗?不须要,向上转型。

②何时向下转型?

须要使用子类型的特有方法时。
可是必定要使用instanceof 进行类型的判断。避免发生classCastException。
 
二、匿名内部类格式:
new 父类(参数列表)或父接口(){
// 匿名内部类实现部分
}

示例

复制代码
 1 interface Animal{
 2     void shout();
 3 }
 4 public class Example18 {
 5     public static void main(String[] args) {
 6         animalShout(new Animal(){
 7             public void shout() {
 8                 System.out.println("喵喵...");
 9             }
10         });
11     }
12     public static void animalShout(Animal an) {
13         an.shout();
14     }
15 }
复制代码

运行结果

喵喵... 
     
     三、Object类是全部类的根类,定义了全部对象都具有的功能,通常状况下均会重写Object的toString()方法,来返回指定的信息。
     示例:
复制代码
 1 class Animal{
 2     /*//定义动物叫的方法
 3     void shout(){
 4         System.out.println("动物叫");
 5     }*/
 6     //重写Object类中的toString()方法
 7 
 8     @Override
 9     public String toString() {
10         return "I am an animal!";
11     }
12 }
13 //定义测试类
14 public class Example16 {
15     public static void main(String[] args) {
16         Animal animal = new Animal();       //建立Animal类对象
17         System.out.println(animal.toString()); //调用toString()方法并打印
18     }
19 }
复制代码

5、异常

       一、Throwable类的继承体系

      

       
 
①错误类(Error类):表示Java运行时产生的系统内部错误或资源耗尽的错误,是比较严重的,仅靠修改程序自己是不能恢复执行的。
②运行时异常与编译时异常:
     编译时异常:在Java中Exception类中除了RuntimeException类即其子类都是编译时异常。特色是编译器会检测的异常,若是出现异常就必须对异常进行处理,不然程序没法经过编译。

     运行时异常:RuntimeException类即其子类都是运行时异常,编译器不会检测的异常,不须要声明。

        ③Throwable经常使用方法
Throwable经常使用方法
方法声明 功能描述
String getMessage() 返回此throwable的详细消息字符串
void printStackTrace() 将此throwable及其追踪输出至标准错误流
void printStackTrace(PrintStream s) 将此throwable及其追踪输出至指定的输出流
二、try...catch和finally
异常捕获:Java中对异常有针对性的语句进行捕获。
语句:
try{
      //须要被检测的语句
}catch(ExceptionType(Exception类及其子类) e) {
      //ExceptionType的处理
}
发生异常后继续执行一段程序
finally{
    //必定会被执行的语句
}

示例

复制代码
 1 public class Example20 {
 2     public static void main(String[] args) {
 3        // 下面的代码定义了一个try...catch语句用于捕捉异常
 4         try {
 5              int result = divide(4,0);  //调用divide()方法
 6              System.out.println(result);
 7         } catch (Exception e) {      //对异常进行处理
 8             System.out.println("捕捉的异常信息为" + e.getMessage());
 9             return;    //用于结束当前语句
10         }finally {
11             System.out.println("进入finally代码块”);
12         }
13        System.out.println("程序继续向下执行...");
14     }
15         //下面的方法实现了两个整数相除
16         public static int divide(int x,int y) {
17             int result = x/y;   //定义一个变量result记录两个整数相除的结果
18             return result;      //将结果返回
19         }
20 }
复制代码

运行结果

捕获的异常信息是:/by zero
进入代码块

在程序设计时,常常会在try...catch后使用finally代码块来完成必须作的事情,例如释放系统资源。需注意,当try...catch中执行了System.exit(0)语句,则退出Java虚拟机,任何代码都不能继续执行。

try catch finally 组合方式:

①try catch :对代码进行异常检测,并对检测的异常传递给catch处理。

       异常捕获处理。
Void show ()throws {//不须要throws
    try{
         throw new Exception();
    }finally{
    }
}

 

②try finally:对代码进行异常检测,检测到异常后由于没有catch,因此同样会被默认jvm抛出。

      异常是没有捕获处理的,可是功能所开启资源须要进行关闭,全部finally只为关闭资源。
Void show () {//须要throws
    try{
         throw new Exception();
    }finally{
    }
}

③try catch finally

       检测异常,并传递给catch 处理,并定义资源释放。

④try catch1 catch2 catch3………

三、throws关键字
①throws关键字声明抛出异常的语法格式以下:
   修饰符 返回值类型 方法名([参数1,参数2…])throws ExceptionType1[,ExceptionType2….]{
    }
② 声明:将问题标识出来,报告给调用者。
   格式:
void show ()throws Exception{
     throw new Exception();
}
        若是函数内经过throw抛出了编译时异常,捕获,那么必须经过throws进行声明,让调用者去处理。
 
四、自定义异常格式:
throw Exception 异常对象
       示例
复制代码
 1 class DivideByMinusException extends Exception{
 2         public DivideByMinusException(){
 3             super();//调用Exception无参的构造方法
 4         }
 5         public DivideByMinusException(String message){
 6             super(message);//调用Exception无参的构造方法
 7         }
 8 }
 9 public class Example26 {
10     public static void main(String[] args) {
11         try{
12             int result = divide(4,-2);
13             System.out.println(result);
14         }catch (DivideByMinusException e){
15             System.out.println(e.getMessage());
16         }
17     }
18     public static int divide(int x,int y)throws DivideByMinusException{
19         if(y<0){
20             throw new DivideByMinusException("被除数是负数");
21         }
22         int result = x/y ;
23         return result;
24     }
25 } 
复制代码
 
6、包的定义与使用
一、Java 中的包是专门用来存放类的,一般功能相同的类存放在相同的包中。
如: 
1 package cn.itcast.chapter04; 
2 public class Example01 {….} 
包的声明只能位于Java源文件的第一行
二、包的导入
import 包名.类名;
      三、经常使用的包
       ①java.lang:包含Java语言的核心类,如String、Math、System和Thread类等,使用这个包中的类无需使用import语句导入,系统会自动导入这个包下的全部类。
       ②java.util: 包含Java中大量工具类、集合类等,例如Arrays、List、Set等。
       ③java.net:包含Java网络编程相关的类和接口。
       ④java.io:包含了Java输入、输出有关的类和接口。
 
7、访问权限修饰符权限:

访问控制级别

 

同一类中

同一包下

(有无关系都可)

不一样包下(子类)

不一样包下

(没有关系)

private

Y

     

default(默认)

Y

Y

   

protected

Y

Y

Y

 

public

Y

Y

Y

Y

 
相关文章
相关标签/搜索