Java基础知识总结

1.什么是类和对象?

EVERYTHING IS OBJECT(万物皆对象)所有的事物都有两个方面:

  • 有什么(属性):用来描述对象。
  • 能够做什么(方法):告诉外界对象有那些功能。
  • 对象:对现实世界中的实体的抽象。在计算机中,是指可标识的存储区域。
  • 类:具有共同属性和行为的对象的抽象。类是创建对象的模板。

 

2.为什么要使用面向对象?

首先,面向对象符合人类看待事物的一般规律。 对象的方法的实现细节对其他对象是屏蔽的。 我们通过类来看待对象,类是对象的抽象。

其次,采用面向对象方法可以使系统各部分各司其职、各尽所能。 对象之间的耦合性一定要低。这样才能使每个对象本身做成最好的。

对于对象的要求:高内聚、低耦合,这样容易拼装成为一个系统。

实现高内聚就是要最大限度低提高复用性(复用性好是因为高内聚)。可复用性是OOP的基础。

 

3.面向过程思想和面向对象思想比较?

面向过程的思想:由过程、步骤、函数组成,以过程为核心;

面向对象的思想:以对象为中心,先开发类,得到对象,通过对象之间相互通信实现功能。  

 

4.实例变量和局部变量的比较

  • 实例变量:定义在类中但在任何方法之外。(New出来的均有初值)
  • 局部变量:定义在方法之中的变量。
  • 局部变量要先赋值,再进行运算,而实例变量均已经赋初值。这是局部变量和实例变量的一大区别。实例变量的对象赋值为null。
  • 不允许在同一作用域内定义两个相同名称的实例变量和局部变量,但实例变量和局部变量允许命名冲突。
  • 区分实例变量和局部变量时一定要写this。

 

5.介绍一下对构造函数的理解

构造方法是当用类生成对象时,系统在生成对象的过程中利用的方法。

  • 注意:构造方法在生成对象的时候会被调用,但并不是构造方法生成了对象。
  • 构造方法没有返回值。格式为:public 方法名。
  • 构造方法的方法名与类名相同。
  • 构造方法是在对象生成的过程中自动调用,不可能利用指令去调用。
  • 在一个对象的生成周期中构造方法只用一次,一旦这个对象生成,那么这个构造方法失效。
  • 注意:在对象变量中存放的是引用(地址);在简单变量中存放的是数值。
  • 可以构造多个构造方法,但多个构造方法的参数表一定不同,参数顺序不同即属于不同的构造方法:
  • 如果我们未给类提供一个构造方法,那么系统会自动提供一个为空的构造方法。

 

6.面向对象方法的重载(Overloading)和覆盖(Overriding)

Overloading在一个类中可以定义多个同名方法,各个方法的参数表一定不同。但修饰词可能相同,返回值也可能相同。 overloading是编译时的多态。

Overriding指子类与父类之间的同名方法,参数表顺序一定相同,但修饰符和返回值可能不同,构造函数无法覆盖。Overriding是运行时多态。  

 

7.this关键字

This表示当前对象。

特别注意:用this调用其他构造方法时,this必须为第一条语句,然后才是其他语句。  

 

8.面向对象三大特性之封装

Java中提供4个修饰符来进行对象属性和方法的访问权限控制:

  • private :类内部可见
  • default :包内部可见
  • protected :包内部或子类可见
  • public :所有可见

 

9.面向对象三大特性之继承

  • 父类的非私有化属性和方法可以默认继承到子类。
  • 父类的构造方法子类不可以继承,更不存在覆盖的问题。(非构造方法可以)
  • 如果子类访问父类的构造方法,则在编译的时候提示访问不到该方法。
  • JAVA中不允许多继承,一个类有且只有一个父类(单继承)。
  • JAVA的数据结构为树型结构,而非网状。(JAVA通过接口和内部类实现多继承)
  • 对于方法的修饰词,子类方法要比父类的方法范围更加的宽泛。父类为public,那么子类为private则出现错误。
  • super()表示调用父类的构造方法。super()也和this一样必须放在第一行。this()用于调用本类的构造方法。如果没有定义构造方法,那么就会调用父类的无参构造方法,即super()。

当构造一个对象的时候,系统先构造父类对象,再构造子类对象。构造一个对象的顺序:(注意:构造父类对象的时候也是这几步)

  1. 递归地构造父类对象;
  2. 顺序地调用本类成员属性赋初值语句;
  3. 本类的构造方法。

 

10.面向对象三大特性之多态

多态指的是编译时类型不变化,而运行时类型变化。 多态分两种:

  • 编译时多态:编译时动态重载;
  • 运行时多态:指一个对象可以具有多个类型。

 

11.修饰符static

static定义的是一块为整个类共有的一块存储区域,其发生变化时访问到的数据都是变化之后的。其变量可以通过类名去访问:类名.变量名。与实例对象访问变量为等价的。 static 可修饰属性、方法和代码块

  • static修饰的属性为一个类的共享变量,属于整个类,在不实例化对象的情况下就能访问。
  • static修饰方法表明此方法为类方法(静态方法),静态方法不需要有对象,可以使用类名调用,静态方法不能访问非静态成员,包括成员的变量和方法,因为此时是通过类调用的,没有对象的概念。this是不可用的。
  • 当static修饰代码块时(注:此代码块要在此类的任何一个方法之外),那么这个代码块在代码被装载进虚拟机生成对象的时候可被装载一次,以后再也不执行了,一般静态代码块被用来初始化静态成员。

一般情况下,主方法是静态方法,所以可调用静态方法,主方法为静态方法是因为它是整个软件系统的入口,而进入入口时系统中没有任何对象,只能使用类调用。 覆盖不适用于静态方法,静态方法不可被覆盖。(允许在子类中定义同名静态方法,但是没有多态,严格的讲,方法间没有多态就不能称为覆盖。  

 

12.修饰符final

final可修改类、属性、方法

  • 当用final修饰类的时候,此类不可被继承,即final类没有子类。这样可以用final保证用户调用时动作的一致性,可以防止子类覆盖情况的发生。
  • 利用final修饰一个属性(变量)的时候,此时的属性成为常量。常量的地址不可改变,但在地址中保存的值(即对象的属性)是可以改变的。
  • 利用final定义方法:这样的方法为一个不可覆盖的方法。如果在父类中有final定义的方法,那么在子类中继承同一个方法。

对于在构造方法中利用final进行赋值的时候,此时在构造之前系统设置的默认值相对于构造方法失效。 常量(这里的常量指的是实例常量:即成员变量)赋值:

  1. 在初始化的时候通过显式声明赋值。final int x=3;
  2. 在构造的时候赋值(定义时不赋值)。

局部变量可以随时赋值。 注:如果一个方法前有修饰词private或static,则系统会自动在前面加上final。即private和static方法默认均为final方法。Java中使用final和static组合,声明常量标识符(固定语法)。final并不涉及继承,继承取决于类的修饰符是否为private、default、protected还是public。也就是说,是否继承取决于这个方法对于子类是否可见。 

 

13.抽象修饰符abstract

  • abstract(抽象)可以修饰类、方法
  • 如果将一个类设置为abstract,则此类不可生成对象,必须被继承使用。
  • abstract可以将子类的共性最大限度的抽取出来,放在父类中,以提高程序的简洁性。
  • abstract虽然不能生成对象,但是可以声明,作为编译时类型,但不能作为运行时类型。
  • final和abstract永远不会同时出现。
  • 当abstract用于修饰方法时,此时该方法为抽象方法,此时方法不需要实现,实现留给子类覆盖,子类覆盖该方法之后方法才能够生效。
  • abstract和static不能放在一起,否则便会出现错误。(这是因为static不可被覆盖,而abstract为了生效必须被覆盖。)

 

14.接口和抽象类的比较

  1. 接口和抽象类都用于抽象,接口是抽象类的抽象。 接口和抽象类都不能被实例化。
  2. 接口中只有方法声明,没有实现;在接口中声明的方法具有public和abstract属性,一个类可以实现多个接口(即多继承),接口以‘,’分隔;接口中的方法必须全部实现。
  3. 抽象类可以有部分方法实现,抽象类必须通过继承才能使用。
  4. 表现目的不同:接口用来声明功能和消息,抽象类用来抽象类,达到代码复用。

 

15.内部类

注:所有使用内部类的地方都可以不用内部类,使用内部类可以使程序更加的简洁,便于命名规范和划分层次结构。内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。

内部类同时具有成员和类的特性(特性不冲突)。 内部类的分类:

  • 成员内部类
  • 局部内部类
  • 静态内部类
  • 匿名内部类(图形是要用到,必须掌握)

a.成员内部类

作为外部类的一个成员存在,与外部类的属性、方法并列。

内部类和外部类的实例变量可以共存。在内部类中访问实例变量:this.属性,在内部类访问外部类的实例变量:外部类名.this.属性。

成员内部类的优点:

⑴内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)

⑵用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。

成员内部类不可以有静态属性。

建立内部类对象时应注意: 在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)而在外部类的外部,要生成(new)一个内部类对象,需要首先建立一个外部类对象(外部类可用),然后在生成一个内部类对象。

Outer outer = new Outer; Outer.Inner in=outer.new Inner();

错误的定义方式: Outer.Inner in=new Outer.Inner()。

注意:当Outer是一个private类时,外部类对于其外部访问是私有的,所以就无法建立外部类对象,进而也无法建立内部类对象。

b.局部内部类

在方法中定义的内部类称为局部内部类。与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块。

注意:局部内部类不仅可以访问外部类实例变量,还可以访问外部类的局部变量(但此时要求外部类的局部变量必须为final)??

在类外不可直接生成局部内部类(保证局部内部类对外是不可见的)。

要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部类。

c.静态内部类

注意:前三种内部类与变量类似,所以可以对照参考变量,静态内部类定义在类中,任何方法外,用static定义。

静态内部类只能访问外部类的静态成员。

生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。

静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner(); 而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。

静态内部类不可用private来进行定义。

注意:当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用内部类来实现。用接口不能完全地实现多继承,用接口配合内部类才能实现真正的多继承。

d. 匿名内部类

匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口。

注:一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名。 因其为局部内部类,那么局部内部类的所有限制都对其生效。

匿名内部类是唯一一种无构造方法类。

匿名内部类在编译的时候由系统自动起名Out$1.class。

如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。因匿名内部类无构造方法,所以其使用范围非常的有限。  

 

15、运行时异常与普通异常

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

Throwable是所有Java程序中错误处理的父类,有两种资类:Error和Exception。
  • Error:表示由JVM所侦测到的无法预期的错误,由于这是属于JVM层次的严重错误,导致JVM无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。
  • Exception:表示可恢复的例外,这是可捕捉到的。
Java提供了两类主要的异常:runtime exception和checked exception。
  • checked异常:也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。
  • runtime exception,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。异常处理的目标之一就是为了把程序从异常中恢复出来。

 

16、Java命名规范

必须以英文字母、下划线(’_’)或’$’开始,其余可以有数字但不允许包含空格,且组合后的名称不能是Java关键字或保留字。

  • 匈牙利命名法:以m开始为类成员变量,以g开始为全局变量,以v开始为本地局部变量,常量命名一般不以下划线、美元符开始。
  • 驼峰命名:一般称由多个单词或缩写组成的变量名,并且该变量名每个单词首字母均为大写(一般类名全部首字母大写,方法或属性名第一个字母小写)的称为驼峰命名。

     

posted @ 2012-01-13 17:12  残夜  阅读(4420)  评论(3编辑  收藏  举报