Java面向对象基础

1、面向过程属于唯心主义思维范畴,面向对象属于唯物主义思维范畴。前者很容易会让程序员的思维变得以自我为中心,变得很难和人相处。后者带给程序员的是一种朴实的平等态度,让程序员更关注与关系,而非单个个体,这样的程序员可能会更好和人相处。性格决定编程风格,编程风格也反过来影响性格,两者相辅相成。

2、对象是用来存储数据的,具体对象就是Java在堆内存中用new标识符创建的实体。

3、成员变量和局部变量:成员变量作用于整个类中,局部变量作用于函数中(或者语句中);成员变量因为对象在堆内存中,所以它在堆内存中,局部变量存在于栈内存中。堆内存中的成员变量不用初始化就拥有默认值,可以参与运算,而栈内存中的局部变量不初始化就不能参与运算。

4、创建类对象:既可以在本类中创建类对象,也可以在其它类中创建类对象。

5、匿名对象:格式是new Car();匿名对象是没有名字的对象,是简化的对象。匿名对象在调用属性的时候没有任何优势,而且会产生垃圾,但当它调用行为时则可以简化程序。匿名对象的优势是:如果对对象的行为只调用一次,可以使用它简化程序。如果对一个对象进行多个成员的调用的时候,则需要添加对象名字。还可以将匿名对象当作实际参数进行传递。

6、封装:封装是指隐藏对象的属性和实现细节,仅对外提供对象的公共访问方式。最小的封装是函数,再上是类对象,再上是包,再上是框架。

7、一个成员变量一般有两个访问方式,一个是设置set,一个是获取get。私有仅仅是封装的一种表现形式。

8、构造函数:特点是没有返回值类型,不用return,函数名和类名相同。对象一旦实例化就会调用与之对应的构造函数。构造函数的作用是可以给对象进行初始化。也就是说,对象一建立就会用构造函数初始化。当一个类中,没有定义构造函数时,系统会默认给该类分一个空参数的构造函数。当类中自定义了构造函数,系统默认的构造函数就不会执行了。定义构造函数的原因是在事物诞生时,它就拥有一些固有的特定,此时需要定义构造函数表现其固有特点。

9、构造函数和一般函数区别:写法不同;前者在对象初始化时就执行,一般函数是在对象调用时才执行。前者在对象建立后只执行依次,后者可以任意次数调用执行。

10、在没有定义静态时,方法只能被对象执行。

11、构造代码快:构造代码块的作用是对象初始化,对象一建立就执行,并且优先于构造函数执行。构造代码快是给所有的对象进行初始化,而构造函数是给特定对象初始化。一般把初始化的时候共性的东西放在构造代码块里。

12、this关键字的用法:可用来区分局部变量和成员变量;哪个对象调用this所在函数,则this指代哪个对象。this是一种模糊手法。当定义类功能时,如果方法内部用到了类对象,可以使用this关键字表示此对象。this对象还用在构造函数之间互相调用,且构造函数间调用只能用this。而且this只能放在构造函数的第一行,因为初始化的动作要先执行。

13、静态修饰符:可以修饰成员包括成员变量和成员函数,静态修饰的成员不在堆内存中了。静态修饰内容被对象所共享。静态成员除了可以被对象调用外,还可以被类名直接调用。静态修饰的前提是类中的某成员被所有的成员所共享。静态的特点是:随着类的加载而加载,优先于对象而存在,直接被类名所调用,随着类的消失而消失,存在的生命周期最长。成员变量又叫实例变量,静态变量又叫类变量。静态变量的局限性是对内存开销大。

14、实例变量和类变量的区别:存放位置不同,类变量随着类的加载而存在与方法区中,随着类的消失而消失在方法区中,实例变量随着对象的建立而存在于堆内存中;生命周期不同,类变量的声明周期最长,随着类的消失而消失,实例对象的生命周期随着对象消失而消失。

15、静态使用的注意点:静态方法只能使用静态成员;非静态方法可以访问静态和非静态成员;静态方法中不可以定义this和super关键字,因为静态方法优先于对象而存在;主函数是静态的。

16、主函数:一个特殊的入口函数,可以被JVM调用,public代表被虚拟机访问的权限是最大的,static代表主函数随着类的加载就存在了,void代表主函数没有返回值类型,main不是关键字,确是一个特殊的单词,可以被JVM识别,String[] args是主函数的参数,是一个数组类型,存放字符串。总之,主函数是固定的格式,是为虚拟机识别的。JVM调用主函数时传入的是new String[0]。

17、静态可以应用于工具类,一般通用的一些方法可以定义在一个类中,类中可以封装静态修饰的方法。通常,工具类里定义的都是静态方法。工具类里构造函数私有化可以防止建立对象。

18、帮助文档的制作:用/**   */来产生帮助文档,必须是public类才可以生存帮助文档,用javadoc.exe生成帮助文档。一个类中空参数的默认构造函数的修饰和类修饰符一样。

19、静态代码块:格式是static{},随着类的加载而加载,并且只加载一次,用于给类初始化,并且优先于主函数执行。

20、类加载的前提是用到了类中的内容。注意:静态代码块、构造代码快、构造函数的执行顺序。

21、对象初始化过程:例如Person p=new Person("wo",20);

  (1) 因为new用到了Personl类,所以系统会先找到Person类文件并加载到内存中;

  (2) 执行该类中的static代码块,如果有,就对Person类进行初始化;

  (3) 在堆内存中开辟空间,分配内存地址,建立对象的特有属性,并进行默认初始化;

  (4) 对属性进行显示初始化;

  (5) 对对象进行构造代码块初始化;

  (6) 对对象进行相应的构造函数的初始化;

  (7) 将内存地址赋给栈内存中的p变量。

22、继承:因为有了继承才有了多态。具有is a关系的类才能继承。继承提高了代码的复用性。继承关系的确定不可以参照代码的简洁性。Java中只支持单继承。一个类只可以继承一个父类,因为多继承会带来安全隐患问题。但Java对多继承进行了改良,以多实现来体现,Java支持多层继承。

23、类与类之间还有聚集关系(包括聚合和组合),是总体与部分之间的关系,组合的关系比聚合要更紧密。

24、具有继承关系的子类创建对象,先加载父类对象后加载子类对象。super代表的是父类对象的引用,this代表的是子类对象的引用。如果this和super在子类中找不到属性,则去父类中找。super一般定义在子类构造函数的第一行。

25、如果子类和父类方法一样,子类则覆盖(重写)父类的方法。子类继承了父类的功能,但子类的功能和父类的不一致,则在子类中没有必要定义新功能,而是使用覆盖特性,保留父类功能,重写子类的功能。项目完成后,在功能扩展时,不对源码修改,而是采用覆盖功能,也可以用super调用父类的功能。子类覆盖父类必须保证子类权限大于父类权限,静态只能覆盖静态。

26、重写和重载:前者是子类函数和父类函数一模一样,后者只看函数参数列表。

27、对子类构造函数初始化时,父类的构造函数也会初始化,因为子类的构造函数的第一行会默认一个调用父类的super();。事实上,所有的子类的构造函数内都有一个调用父类构造函数的函数。如果父类没有空参数的构造函数,子类要手动通过super();语句访问父类的构造函数。

28、final是一个修饰符,可以修饰类、函数、变量。被final修饰的类(最终类)不可以被继承。被final修饰的方法不可以被复写。final修饰的变量只可以被赋值一次,是一个常量,它既可以修饰成员变量,也可以修饰局部变量。

29、当多个类中出现相同功能,但功能主体不同的方法,也可以向上抽取,这时只抽取功能定义。抽象类的特定是:抽象方法一定在抽象类中;抽象方法和抽象类都必须被abstract关键字修饰;抽象类不可以用new创建对象,因为调用抽象方法没意义;抽象类中的方法要被使用必须由子类复写其所有的抽象方法后建立子类对象调用,如果子类只覆盖了部分方法,该子类还是一个抽象类。抽象类里既有抽象方法又有一般方法。抽象类中不定义抽象方法,一个目的就是不让该类建立对象。

 30、接口可以理解为一个特殊的抽象类,接口中的方法都是抽象的。接口中常见的定义是常量和抽象方法,常量修饰符是public static final,方法修饰符是public abstract 。接口中的成员都是public的,默认也是public。Interface修饰符下的内容都是默认补齐格式修饰符的。接口不能创建对象,因为有抽象方法,并且需要被子类实现,当子类把接口中的抽象方法都实现了,子类才可以实例化,否则子类是一个抽象类。接口也是编译成.class文件。

31、一个类可以实现多个接口(多实现),这是对多继承不支持多继承的弥补形式。接口之间可以多继承。

32、多态:可以理解为事物存在的多种表现形态。多态的表现是父类的引用指向了自己的子类对象,也就是说父类的引用也可以接收子类的对象。多态的好处:提高了程序的扩展性。多态的前提是类与类之间有关系,要么是继承要么是实现,通常需要存在覆盖才能使用。多态的弊端是只能用父类的引用访问父类的成员。

33、父类的引用指向了自己的子类的对象时,此时的父类引用可以提升类型也可以降低类型,即可以转化,不可以单独地强制对父类引用转换。

34、多态中非静态成员函数的特点:在编译时期,检查引用型变量所属的类中是否有调用的方法,如果有,编译通过,没有则编译失败。在运行时期,检查对象所属的类中有没有要调用的方法。简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。多态中成员变量和静态成员函数的特定:不论编译还是运行都是参照左边。静态绑定(绑定类)和动态绑定(绑定对象)。

35、Object类是所有类的父类,是一个超类。它里面定义的是所有对象共有的属性。所有类都隐式地调用Object类,即extends Object。Java认为所有对象都具有比较性。Object类的特性基本上是需要重写的。

36、内部类:在类内部也可以定义一个或多个类,内部类private成员也可以又内部类访问,如果外部类要访问内部类就需要建立内部类对象。Outer.Inner i=new Outer().new Inner();内部类之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式为 外部类名.this。当内部类在外部类的成员位置上,并且非私有,其它任意外部类都可以实例化内部类对象,内部类在外部类成员位置上就可以使用成员变量的修饰符比如private,static,被static修饰的内部类就具有了静态的特征,内部类只能访问外部类的静态成员。外部类访问静态内部类中的非静态方法和静态内部类中的静态方法都有固定的格式,分别是new Outer.Inner().function();和Outer.Inner.funtion();。此外,内部类中定义了静态成员,该内部类必须是静态的;当外部类中的静态方法访问内部类时,内部类也必须是静态的。

37、内部类使用:当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容。

38、内部类定义在局部时不可以被成员修饰符修饰,只可以被final和abstract修饰,可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问它所在的局部内的变量,只能访问被final修饰的局部变量。

39、匿名内部类:内部类就是匿名内部类的简称;定义匿名内部类的前提是内部类继承一个类或实现接口。匿名内部类的格式是:new 父类或接口(){定义子类的内容}。其实匿名内部类就是一个匿名子类对象,而且这个对象是比较胖。匿名内部类中的方法最好不要超过3个。

40、异常:指程序在运行时(而非编译)遇到了不正常的现象。异常是Java对不正常的情况描述后的类抽象。异常也可以以面向对象的一种情况来处理。对于异常问题的划分有两种,严重的异常和不严重的异常。严重的异常用Error类来处理,不严重的用Exception类处理,前者是虚拟机处理的,我们不需要用代码来处理,对于后者可以针对性地处理。两种类型的异常的共性抽象出来一个父类是Throwable类。

41、异常的处理:用try{需要检测的代码}catch{处理方法}finally{一定会执行的语句}来处理。也可以在函数上声明异常,throws来抛出异常,提高安全性,让调用的函数处理,不处理则编译失败。

42、多异常处理:函数使用throws抛出几个异常就需要几个catch来处理,要有针对性地具体地抛出异常和处理异常;如果多个catch块中的异常出现继承关系,父类异常要放在最下边,不要定义多余的catch块。异常处理代码一般不要打印,而是用用户能看懂的方式,比如异常日志。

43、自定义异常方法一:java未解决的异常,我们通过面向对象的思想建立异常,当函数内部出现了throw抛出的异常对象,那就必须进行处理。要么内部try,catch处理,要么在函数上声明,让调用者处理。一般在函数内出现异常,要在函数上声明出来。如果要输出具体的异常信息,因为父类已经定义了所以子类只需要调用就可以了。自定义异常要继承父Exception,因为异常体系有一个特点,异常类和异常对象都会被抛出,而且只有这个Throwable体系中才可以用throw和throws抛出。

44、throw和throws的区别:前者出现在函数内,后者出现在函数上。前者跟的是异常对象,后者跟的是异常类,可以有多个类用逗号隔开。

45、Exception中有一个特殊的子类异常,叫RuntimeException运行时异常。如果在函数内抛出此异常,函数上不用可以不用声明,编译通过;如果在函数上声明了此异常,调用者可以不用处理,编译照常通过。不在函数上声明是为了不让调用者处理,因为此时我们希望程序停止,查看异常情况。

46、自定义异常方法之二:如果该异常发生,不希望再继续进行运算,就让自定义异常继承RuntimeException。异常分为编译时被检测的异常和编译时不被检测的异常(运行时异常,RuntimeException异常极其子类)。

47、finally是一定要执行的语句,可以用到一定要释放的资源,关闭资源。多层抛出体现了问题的封装性。

48、异常有三种格式:(try,catch,finally),(try,catch)和(try,finally)。

49、子类覆盖父类时,如果父类的方法抛出了一个异常,那么子类覆盖父类的方法必须抛出父类的异常或父类异常的子类或者什么也不抛出;如果父类的方法抛出多个异常时,子类在覆盖父类方法时只能抛出父类的子集;如果父类或者接口的方法中没有抛出异常,子类覆盖时不可以抛出异常,如果子类有其它异常,则必须用try在内部处理,绝对不可以抛出。

50、导入包及包中的类:建议不要使用通配符*,包中的类相同需要连包名也写才能调用。建立包名一般不要重名,一般用URL来定义包名。

原文地址:https://www.cnblogs.com/joeshine/p/4381045.html