javaSE入门 四、面向对象

面向对象

System.exit(0); 【退出JVM】
面向对象编程的核心:定义好类,然后将类实例化为对象,给一个环境驱使一下,让各个对象之间协作起来形成一个系统。

总结

一个类中,我们可以编写哪些东西
class 类{
静态代码块; //类加载的时候执行,只执行一次
实例代码块 //构造方法执行之前执行,构造方法执行一次,实例代码块执行一次

  静态变量;      //在类加载的时候初始化,存在于方法区内存,通过"类名."的方式访问
  实例变量;      //构造方法执行的时候初始化,存在于堆内存当中java对象内部,通过"引用."的方式访问

  构造方法;      //构造方法用于创建对象,通过new关键字调用

  静态方法;      //采用"类名."的方式调用
  实例方法;      //采用"引用."的方式调用

}

提倡:面向对象的编程,不要面向具体编程。
面向对象编程的好处是,耦合度低,扩展力强。

1、面向过程和面向对象的区别

-面向对象: 主要关注点是:实现的具体过程,因果关系【集成显卡的开发思路】
* 优点:对于业务逻辑比较简单的程序,可以达到快速开发,前期投入成本较低
* 缺点:采用面向过程的方式开发很难解决非常复杂的业务逻辑,另外面向过程的
方式导致软件元素之间的“耦合度”非常高,只要其中一环出问题,整个系统受到影响,
导致最终的软件扩展力差。另外,由于没有独立体的概念,所以无法达到软件复用

-面向对象: 主要关注点是:主要关注对象【独立体】能完成哪些功能。【独立显卡的开发思路】
* 优点:耦合度低,扩展力强,更容易解决显示世界当中更复杂的业务逻辑。组件复用性强
* 缺点:前期投入成本较高,需要进行独立体的抽取,大量的系统分析与设计

-c语言是面向过程的,c++半面向对象,java纯面向对象

2、面向对象的三大特征

  • 封装
  • 继承
  • 多态

所有面向对象的编程语言都有这三大特征。

采用面向对象的方式开发一个软件,生命周期当中:【整个生命周期中贯穿使用OO面向对象方式】
* 面向对象的分析:OOA
* 面向对象的设计:OOD
* 面向对象的编程:OOP

3、类和对象的概念

  • 什么是类?
    -类在现实世界当中是不存在的,是一个模板,是一个概念,是人类大脑思想抽象的结果
    -类代表了一类事物
    在现实世界当中,对象A与对象B之间具有共同特征,进行抽象总结出一个模板,这个模板被称为类

  • 什么是对象?
    -对象是实际存在的个体,现实世界当中实际存在。

  • 描述软件开发的过程:
    程序员先观察现实世界,从现实世界中寻找对象
    寻找了N多个对象之后,发现所有的对象都有共同特征
    程序员在大脑中形成了一个模板【类】
    java程序员可以通过java代码来表述一个类
    java程序中有了类的定义
    然后通过类就可以创建对象
    有了对象之后,可以让对象直接协作起来形成一个系统

  • 类–【实例化】–>对象

  • 对象又被称为实例/instance

  • 对象–【抽象】–>类

*重点:
类描述的是对象的共同特征。
共同特征例如:身高特征
这个身高特征在访问的时候,必须先创建对象,通过对象去访问这个特征,
因为这个特征具体在某个对象上之后,值不同。有的对象身高1.80,有的
对象身高2.80.

*一个类主要描述什么信息呢
一个类主要描述的的是:状态 + 动作
状态信息:名字、身高、性别、年龄
动作信息:吃、唱歌、跳舞、学习

 状态-->一个类的属性
 动作-->一个类的方法
  • 类{
    属性; //描述对象的状态信息
    方法; //描述对象的动作信息
    }
    注意:状态和动作当具体到某个对象上之后,发现最终的结果可能不一样
    对象和对象之间有共同特征,但是具体到对象之后有数据的差异

4、类的定义

语法结构:
[修饰符列表] class 类名{
属性;
方法;
}

学生类,描述所有学生对象的共同特征:
学生对象有哪些状态信息:
* 学号【int】
* 名字【String】
* 性别【boolean】
* 年龄【int】 (年龄是一个属性,年龄是一个数据,是数据就有数据类型)
* 地址【String】

 学生对象有哪些动作信息:
* 吃饭
* 睡觉
* 学习
* 玩
* 唱歌
* 跳舞
......

 重点:属性通常是采用一个变量的形式来完成定义的

* 引用数据类型
  String.class  SUN提供的
  System.class  SUN提供的

  User.class    程序员自定义的
  Product.class    程序员自定义的
  Customer.class    程序员自定义的
  ......
  以及之后自己编写的类,都属于引用数据类型

*java语言中所有的class都属于引用数据类型

5、类体=属性+方法

例:public class Stydent{
    int no;
}
属性【存储数据采用变量的形式】
由于变量定义在类体当中,方法体之外,这种变量被称为成员变量
所有学生都有序号信息
但是每一个学生的学号都是不同的
所以要访问这个学号必须先创建对象,通过对象去访问学号信息
学号信息不能直接通过"类"去访问,所以这种成员变量又被叫做:实例变量
对象又被称为实例,实例变量又被称为对象变量。【对象级别的变量】
不创建对象,这个no变量的内存空间是不存在的,只有创建了对象,这个no变量内存空间才会创建

6、对象的创建和使用

通过一个类可以实例化N个对象
实例化对象的语法:new 类名();
new是java语言当中的一个运算符
new运算符的作用是创建对象,在JVM堆内存当中开辟新的内存空间
方法区内存:在类加载的时候,class字节码代码片段被加载到改内存空间中
栈内存(局部变量):方法代码片段在执行的时候,会给该方法分配内存空间,在栈内存中压栈。
堆内存:new的对象在堆内存中存储

什么是对象?new运算符在堆内存中开辟的内存空间称为对象。
什么是引用?引用是一个变量,只不过这个变量中保存了另一个java对象的内存地址
java语言当中,程序员不能直接操作堆内存,java中没有指针,不像c语言。
java语言当中,程序员只能通过"引用"去访问堆内存当中对象内部的实例变量
Student s = new Student();

访问实例变量的语法格式:
读取数据:引用.变量名 【读取get】
修改数据:引用.变量名 = 值; 【修改set】

**扩展**  
  ***
  1)堆内存和方法区内存各有一个,栈内存可以有多个,一个线程一个栈内存)
  2)方法调用的时候,该方法所需要的内存空间在栈内存中分配,称为压栈。
  方法执行结束之后,该方法所属的内存空间释放,称为弹栈。
  3)栈中主要存储的是方法当中的局部变量。
  4)方法的代码片段以及整个类的代码片段都存储在方法区内存当中,在类加载的时候这些代码片段会载入。
  5)在程序执行过程中使用new运算符创建的java对象,存储在堆内存当中,对象内部有实例变量,所以实例变量存储在堆内存当中。
  6)变量分类:
     - 局部变量【方法体中声明】
 - 成员变量【方法体外声明】
        *实例变量       【前边修饰符没有static】
	*静态变量/类变量【前边修饰符中有static】
  7)静态变量存储在方法区内存当中
  8)三块内存当中变化最频繁的是栈内存,最先有数据的是方法区内存,垃圾回收器主要针对的是堆内存
  9)垃圾回收器【垃圾自动回收机制,GC机制】什么时候会考虑讲整个java对象的内存回收呢
     当堆内存当中的java对象成为垃圾的时候,会被垃圾回收器回收。
 什么时候堆内存中的java对象变成垃圾
     没有更多的引用指向它的时候
     这个对象无法被访问,因为访问对象只能通过引用的方式访问
 
  java.lang.NullPointerException
  运行出现空指针异常
  空引用访问"实例"相关的数据一定会出现空指针异常
  ("实例"相关的数据表示:这个数据访问的时候必须有对象的参与,这种数据就是实例相关的数据)

7、面向对象封装性

封装的好处
- 封装之后,归于那个事物来说,看不到这个事物比较复杂的那一面,只能看到该事物简单的那一面。
复杂性封装,对外提供简单的操作入口。照相机就是一个很好的封装的案例,照相机实现原理非常复杂,
但是对于使用照相机的人来说,操作起来是非常方便、非常便捷的。还有电视机也是封装的,电视机
内存实现非常复杂,但是对于使用者来说不需要关心内部的实现原理,只需要会操作遥控器就行。

  - 封装之后才会形成真正的"对象",真正的"独立体"。

  - 封装就意味着以后的程序可以重复使用。并且这个事物应该适用性比较强,在任何场合都可以使用。

  - 封装之后,对于事物本身,提高了安全性。【安全级别高】

封装的步骤:
1)所有属性私有化,使用private关键字进行修饰,private表示私有的,修饰的所有数据只能在本类中访问。
2)对外提供简单的操作入口,也就是说以后外部程序要想访问age属性,必须通过这些简单的入口进行访问。
- 对外提供两个公开的方法,分别是set方法和get方法
- 想要修改age属性,调用set方法
- 想要读取age属性,调用get方法
【在set方法和get方法执行过程中可以进行安全过滤,一般与if语句结合】
3)set方法的命名规范:
public void set+属性名首字母大写(形参){
}
例:public void setAge(int a){
age = a;
}
4)get方法的命名规范:
public int getAge(){
return age;
}

  例:
    public class User{
    private int age;
}

注意:
* setter and getter方法没有static关键字
* 有static关键字修饰的方法怎么调用:类名.方法名(实参);
* 没有static关键字修饰的方法怎么调用:引用.方法名(实参);

8、构造方法

1)构造方法又被称为构造函数/构造器/Constructor
2)构造方法语法结构:
[修饰符列表] 构造方法名(形式参数列表){
构造方法体;
}
3)回顾普通方法的语法结构:
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
4)对于构造方法来说,"返回值类型"不需要指定,并且也不能写void,
只要写上void,那么这个方法就成为普通方法了。
5)对于构造方法来说,构造方法的方法名必须和类名保持一致。
6)构造方法的作用
构造方法存在的意义是,通过构造方法的调用,可以创造对象。
7)构造方法应该怎么调用
-普通方法是这样调用的:有static关键字修饰的方法:类名.方法名(实参);
没有static关键字修饰的方法:引用.方法名(实参);
-new 构造方法名(实参列表);
【按住ctrl键,鼠标移动到查看的元素上,出现下划线的时候单击】
【crtl+o,可以查看当前类中的属性和方法,然后输入要查找的元素名称,该名称不一定输入全名称】
8)构造方法调用执行之后,有返回值吗?
每一个构造方法实际上执行结束之后都有返回值,但是这个"rturn值;"这样的语句不需要写。构造方法结束的时候java程序
自动返回值,并且返回值类型是构造方法所在类的类型,由于构造方法的返回值类型就是类本身,所以返回值类型不需要编写。
9)注释和取消注释:ctrl + / ,多行注释:ctrl + shift + /
10)当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为缺省构造器
11)当一个类显示的构造方法定义出来了,那么系统则不再默认为这个类提供缺省构造器。
建议开发中手动的为当前类提供无参构造方法,因为无参构造方法太常用了。
12)构造方法支持重载机制。在一个类当中编写多个构造方法,则这多个构造方法显然已经构成方法重载机制。
13)构造方法的作用
* 创建对象
* 创建对象的同时,初始化变量的内存空间【给实例变量赋值】

9、对象和引用:

  • 对象:目前在使用new运算符在堆内存中开辟的内存空间称为对象。
  • 引用:是一个变量,不一定是局部变量,还可能是成员变量,引用保存了内存地址,指向了堆内存当中的对象。
  • 所以访问实例相关的数据,都需要通过"引用."的方式访问,因为只有通过引用才能找到对象。
  • 只有一个空的引用,访问对象的实例相关的数据会出现空指针异常。

10、数据传递

java语言当中方法调用的时候涉及到参数传递的问题,java只遵循一种语法机制,
就是将变量中保存的具体“值”传递过去了,只不过有时候这个值是一个字面值10,
有时候这个值是另一个java对象的内存地址0x1234.

int i = 10; //此时i中保存的为10这个字面值
add(i); 等同于:add(10);

Uear u = new Uear(20); //此时u中保存的为Uear对象在堆内存当中的内存地址
add(u); 等同于:add(0x1234);

11、this关键字

 * this是一个关键字,翻译为:这个
 * this是一个引用,this是一个变量,this变量中保存了内存地址指向了自身,this存储在JVM堆内存java对象内部。
 * 创建100个java对象,每一个对象都有this,也就是说有100个不同的this。
 * this可以出现在"实例方法"当中,this指向当前正在执行这个行为/动作的对象(this代表当前对象)
   例:当使用c1去访问该对象的话,整个过程出现的this就是c1
       当使用c2去访问该对象的话,整个过程出现的this就是c2
 * 注意:当一个行为/动作执行的过程中是需要对象参与的,那么这个方法一定要定义为"实例方法",不要带static关键字
 * this在多数情况下都是可以省略不写的
 * this不能使用在带有static关键字的方法中
    - 带有static的方法是通过类名的方式访问的,执行过程中没有当前对象
      或者说这个"上下文"当中没有"当前对象",自然也不存在this(this代表的是的当前正在执行这个动作的对象)
    - 注意:带有static的方法不是对象去调用,是一个类名去调用,执行过程中没有"当前对象",而实例变量访问的时候
            必须通过"类名."的方式来访问,带static的方法中没有当前对象,也就不能访问当前对象的实例变量(所以不能使用this)
	若想在带static的方法中访问实例变量,可以新创建一个对象,用新创建的对象去访问(此时已经不是当前对象this了)
- 带有static的方法,其实即可以采用类名的方式访问,也可以采用引用的方式访问,
  但是即使采用引用的方式去访问,实际上执行的时候和引用执行的对象无关
  (即当引用=null的时候,引用.方法仍可以访问,不会出现空指针异常,会默认转为类名.方法,所以此时的方法调用与引用对象根本没有关系)
 * 在带有static的方法当中不能"直接"访问实例变量和实例方法。因为实例变量和实例方法都需要对象的存在。
   而static的方法当中是没有this的,也就是说当前对象是不存在的,自然也就无法访问当前对象的实例变量和实例方法。
 * "this."在用来区分局部变量和实例变量的时候,不能省略

 * 构造方法中可以调用另一个构造方法
  (注意不要新建对象,使用this(实参);的方式,但是这个语句只能出现在第一行)
   例:  public Date() {
           //若想在无参构造方法中默认日期为"1970-1-1"
       /*  this.year = 1970;
	   this.month = 1;
	   this.day = 1;   */
       //也可以不用重复的编写代码,即:
        this(1970,1,1);
         }
     public Date(int year , int month , int day) {
             this.year = year;
	 this.month = month;
	 this.day = day;
         }

super关键字

  super 不是引用,super也不保存内存地址,super也不指向任何对象。
  super代表的是"当前对象(this)"的那部分"父类型特征"。
  super(实参)的作用是:初始化"当前对象(this)"的"父类型特征"。
     并不是创建新对象。实际上对象只创建了一个。
  
  1)super是一个关键字,全部小写。
  2)super和this对比着学习
      this:
      this能出现在实例方法和构造方法中。
      this的语法是"this.","this()"
      this不能使用在静态方法中
      this.大部分情况下是可以省略的。【表示当前对象的属性】
      this.什么情况下不能省略呢?在区分局部变量和实例变量的时候不能省略
          public void setNum(String name){
	      this.name = name;
	  }
          this() 只能出现在构造方法第一行,通过当前的构造方法去调用"本类"中的
      其他构造方法,目的是:代码复用。
      super:
      super能出现在实例方法和构造方法中。
      super的语法是"super.","super()"
      super不能使用在静态方法中
      super.大部分情况下是可以省略的。【表示当前对象的父类型特征中的属性】
      super.什么情况下不能省略呢?
          父类与子类中存在同名属性或者相同方法,想在子类型中访问父类型的这个
	  属性特征/方法,则super.不能省略
          super() 只能出现在构造方法第一行,通过当前的构造方法去调用"父类"中的
      其他构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
      super.属性名    【访问父类的属性】
      super.方法名(实参) 【访问父类的方法】
      super(实参)     【访问父类的构造方法】

   3)super()
      表示通过子类的构造方法调用父类的构造方法。
  模拟现实世界中的这种场景:要想有儿子,需要现有父亲
   4)重要的结论:
      当一个构造方法第一行:
     既没有this()又没有super()的话,默认会有一个super();
     表示通过当前子类的构造方法调用父类的无参构造方法。
     所以必须保证父类的无参构造方法是存在的。
   5)注意:
      this()和super() 不能共存,他们都是出现在构造方法第一行。
   6)父类构造方法是一定会执行的。(百分百的)
      【在子类的有参构造中有this(),会调用子类的无参构造,此时子类的
    无参构造中第一行会默认存在super(),去调用父类的无参构造】
  【在java语言中不管是new什么对象,最后老祖宗Object类的无参构造方法
    一定会执行,而且是最先执行完的(Object类的无参数构造方法是处于"栈顶部")】

12、static关键字

* 加了static关键字的变量,称为静态变量
* 静态变量在类加载的时候初始化,内存就开辟了,静态变量存储在方法区内存当中
* 访问时不需要创建对象,直接使用"类名.静态变量名"的方式访问
* static修饰的方法是静态方法
  static修饰的变量是静态变量
  static修饰的所有元素都是类级别的特征,和具体的对象无关

* 什么时候成员变量声明为实例变量
      - 所有对象都有这个属性,但是这个属性的值会随着对象的变化而变化【不同对象的这个属性具体的值不同】
  什么时候成员变量声明为静态变量   
      - 所有对象都有这个属性,并且所有对象的这个属性的值是一样的,建议定义为静态变量,节省内存的开销

* 方法什么时候定义为静态的
    方法描述的动作,当所有的对象执行这个动作的时候,最终产生的影响是一样的,那么这个动作
已经不再属于某一个对象的动作了,可以将这个动作提升为类级别的动作,模板级别的动作。
* 静态方法中无法直接访问实例变量和实例方法。
* 大多数方法都定义为实例方法,一般一个行为或者一个动作在发生的时候,都需要对象的参与。
  但是也有例外,例如:大多数"工具类"中的方法都是静态方法,因为工具类就是方便编程,为了
  方便方法的调用,自然不需要new对象是最好的

* 可以使用static关键字来定义"静态代码块":
  1)语法格式:
      static{
     java语句;
  }
  2)静态代码块在类加载时执行,并且只执行一次
  3)静态代码块在一个类中可以编写多个,并且遵循自上而下的顺序依次执行
  4)静态代码块的作用是什么?怎么用?用在哪儿?什么时候用?
      - 和具体的需求有关,例如项目中要求在类加载的时刻/时机执行代码完成日志的记录。
    那么这段记录日志的代码就可以编写到静态代码块当中,完成日志记录。
  - 静态代码块是java为程序员准备的一个特殊时刻,这个特殊的时刻被称为类加载时刻。
    若希望在此刻执行1一段特殊的程序,这段程序可以直接放到静态代码块当中。
  5)通常在静态代码块当中完成预备工作,先完成数据的准备工具,例如:初始化连接池,解析XMI配置文件...

  - 没有static修饰的为"实例代码块/语句块"
     语法格式:
     {
         代码块//
     }
     - 实例代码块可以编写多个,也是遵循自上而下的顺序依次执行。
 - 在构造方法执行之前执行,构造方法执行一次,实例代码块对应执行一次。
 - 实例代码块也是java语言为程序员准备的一个特殊的时机,这个特殊时机被称为:对象初始化时机。
注意:静态代码块与实例代码块都是在类体之中编写。

13、继承

1)继承是面向对象三大特征之一。
2)继承"基本"的作用是:代码复用。但是继承最"重要"的作用是:有了继承才有了以后"方法的覆盖"和"多态机制"。
3)继承语法格式:
[修饰符列表] class 类名 extends 父类名{
类体 = 属性 + 方法
}
4)java语言当中的继承只支持单继承,一个类不能同时继承很多类,只能继承一个类。在c++中支持多继承。
5)关于继承中的一些术语:
B类继承A类,其中:
A类称为:父类、基类、超类、superclass
B类称为:子类、派生类、subclass
6)在java语言当中子类继承父类都可以继承哪些数据呢
- 私有的不支持继承
- 构造方法不支持继承
- 其他数据都可以继承
7)虽然java语言中只支持单继承,但是一个类也可以间接继承其他类,例如:
C extends B{
}
B extends A{
}
A extends T{
}
C类直接继承B类,但是C类间接继承T、A类。
8)java语言中假设一个类没有显示继承任何类,该类默认继承JavaSE库当中提供的java.lang.Object类。
java语言中任何一个类中都有Object类的特征。
9)但凡满足 is a 的都可以设置为继承。

14、方法的覆盖

1)方法覆盖又被称为方法重写,英语单词:override【官方的】/overwrite
2)什么时候使用方法重写?
当父类中的方法已经无法满足子类的业务需求,子类有必要将继承过来的方法进行重新编写,
这个重新编写的过程称为方法重写/方法覆盖
3)什么条件满足之后发生方法重写?【代码满足什么条件之后,构成方法的覆盖呢?】
* 方法重写发生在具有继承关系的父子类之间
* 方法重写的时候:返回值类型相同、方法名相同、参数列表相同
* 方法重写的时候:访问权限不能更低,可以更高
* 方法重写的时候:抛出异常不能更多、更宽泛,只能更少
4)建议方法重写的时候尽量复制粘贴,不要编写,容易出错,导致没有产生覆盖。
5)注意:
私有方法不能继承,所以不能覆盖。
构造方法不能继承,所以不能覆盖。
静态方法不存在覆盖。
覆盖只针对方法,不针对属性。

注意:方法继承与方法覆盖都是继承或者覆盖直接父类的方法,与间接父类没有关系。

15、多态

新创建的对象是哪个类的,之后引用调用的就是那个类的方法(存在继承关系时)
【有可能是从父类继承过来的,也可能是重写的,但一定是调用本类中的方法】
记住:底层是什么对象,就调用这个对象的什么方法。

1)关于多态中涉及的几个概念:

   * 向上转型(upcasting)
       子类型 --> 父类型
   又被称为:自动类型转换
   * 向下转型(downcasting)【只有当访问子类对象当中特有的方法时,才需要向下转型】
       父类型 --> 子类型
   又被称为:强制类型转换。【需要加强制类型转换符】
   *需要记忆:
      无论是向上转型还是向下转型,两种类型之间必须有继承关系。
  没有继承关系,程序是无法编译通过的。

  java中允许这种语法:父类型引用指向子类型对象。
  例:
     Animal a2 = new Cat();    //Cat类为子类,Animal类为父类
     a2.move();    //此时a2为Animal类,Animal类中存在move方法,所以可以编译通过。
               但是在运行阶段由于新建的为Cat对象,所以会运行Cat类中重写的move方法。
   * java程序永远都分为编译阶段和运行阶段。
   * 先分析编译阶段,在分析运行阶段,编译无法通过,根本是无法运行的。
   * 编译阶段编译器检察a2这个引用的数据类型为Animal,由于Animal.class字节码当中有
     move()方法,所以编译通过了。这个过程我们称为静态绑定,编译阶段绑定。只有静态绑定
 成功之后才有后续的运行。
   * 在程序运行阶段,JVM堆内存当中真是创建的是Cat对象,那么以上程序在运行阶段一定会
     调用Cat对象的move()方法,此时发生了程序的动态绑定,运行阶段绑定。
   * 无论是Cat类有没有重写move方法,运行阶段一定调用的是Cat对象的move方法,因为底层
     真实对象就是Cat对象。
   * 父类型引用指向子类型对象这种机制导致程序存在编译阶段绑定和运行阶段绑定两种不同的形态/状态,
     这种机制可以称为一种多态语法机制。

Cat类中存在特有的抓老鼠catchMouse()方法
需求:若想让以上的对象执行catchMouse()方法,怎么办?
   a2是无法直接调用的,因为a2的类型是Animal,Animal中没有catchMouse()方法。
   我们可以将a2强制转换为Cat类型.
   a2的类型是Animal(父类),转换成Cat类型(子类),被称为向下转型/downcasting/强制类型转换
         注意:向下转型也需要两种类型之间必须有继承关系,不然编译报错。强制类型转换要加强制类型转换符。

 什么时候需要使用向下转型呢?
     当调用的方法或者访问的属性是子类中特有的,在父类当中不存在,必须进行向下转型。

   Cat c2 = (Cat)a2;
   c2.catchMouse();

例:
  Animal a3 = new Bird(); 
  Cat c3 = (Cat)a3;
    * 以上程序编译是没有问题的,因为编译器检查到a3的数据类型是Animal,
      Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型,
      父类型转换成子类型叫做向下转型,语法合格。
    * 程序虽然编译通过了,但是程序在运行阶段会出现异常,因为JVM堆内存
      当中真实存在的对象是Bird类型,Bird类型无法转换成Cat对象,因为两种
      类型之间不存在任何继承关系,此时出现了著名的异常:
               java.lang.ClassCasException
	       类型转换异常,这种异常总是在"向下转型"的时候发生。

2)instanceof运算符

  * 语法格式:
     (引用 instanceof 数据类型名)
  * 以上运算符的执行结果是布尔类型,结果可能是true/false
  * 关于运算结果true/false
      假设(a instanceof Animal)   //表示‘a是Animal类型的实例吗’
  true表示:
      a这个引用指向的对象是一个Animal类型
  false表示:
          a这个引用指向的对象不是一个Animal类型

   则上述类型转换异常的程序,可以采用以下写法
     if(a3 instanceof Cat){
     Cat c3 = (Cat)a3;
     c3.catchMouse();
 }else if(a3 instanceof Bird){
     Bird b2 = (Bird)a3;
 }

  java规范中要求:在进行强制类型转换之前,建议采用instanceof运算符进行判断,
                  避免出现类型转换异常,这是一种编程的好习惯。

3)多态的作用

   降低程序的耦合度,提高程序的扩展力。
   能使用多态尽量使用多态
   父类型引用指向子类型对象

   核心:面对抽象编程,不要面对具体编程

16、final关键字

final是一个关键字,表示最终的,不可变的。
final修饰的类无法被继承
final修饰的方法无法被覆盖
final修饰的变量一旦赋值之后,不可重新赋值【不可二次赋值】
final修饰的实例变量【实例变量使用final修饰之后,必须手动赋值,不能采用系统默认值。
在实例变量声明时赋值或者在构造方法中赋值,本质上没有区别】
final修饰的引用【final修饰的引用,一旦指向某个对象之后,不能再指向其他对象,那么被指向的对象无法被垃圾回收器回收,
除非main方法结束(java虚拟机退出),但是被指向的对象内部的内存是可以被修改的】
常量定义的语法格式:
public static final 类型 常量名 = 值;
java规范中要求所有的常量的名字全部大写,每个单词之间使用下划线连接。

关于myeclipse怎么链接源码?
打开某个字节码文件,当没有看到源码的时候:
点击"Attached Source":
- Workspace…【源码在当前的工作区当中】
- External Flle…【源码在某个压缩包当中】
- External Folder…【源码在某个目录当中】
以后尽量所有的程序都链接源码,没有源码从网上找,或者跟老师要源码,养成看源码的好习惯。
关于以后要学习的类库,一般都是包括三个部分的:
- 源码【可以看源码来理解程序】
- 字节码【程序开发过程中使用的就是这部分】
- 帮助文档【对开发提供帮助】
注意使用的时候版本统一

关于java的集成开发环境【集成开发环境简称:IDE】

1、什么是集成开发环境?
* 集成开发环境讲究一站式开发,使用这个工具即可。有提示功能,有自动纠错功能。
* 集成开发环境可以让软件开发变得更简单、更高效。
* 没有IDE工具:
- 需要安装JDK、需要配置环境变量、需要手动的将java源文件编译生成class字节码文件
- java源程序出错之后还没有提示
- 没有自动提示功能
* 有IDE工具:
- 不需要独立安装JDK【IDE中已经集成】
- 不需要手动配置环境变量
- 不需要使用javac命令对java源文件进行编译
- 并且java源程序编写语法错误马上有提示
使用IDE工具有很多代码不需要写,自动生成了

2、java有哪些比较牛的IDE
* eclipse(myeclipse)
* Intellij IDEA
* NetBeans
* JBuilder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值