Java - 面向对象

Object类:
 是java中所有类的根基类,所有类都直接或间接继承自这个类;没有指定父类的类都默认继承自它,都会从它那继承11个方法(Object的全部方法);
 11个方法:
  第一类方法:toString、equals、hashCode;
  第二类方法:clone、finalize、getClass;
  第三类方法:3个wait、notify、notifyAll;
 方法详解:
  toString:用于描述当前对象的有关信息;一般会被重写;打印类对象时,会自动调用此对象的toString方法;
  equals:比较的是对象的引用是否指向同一块内存地址;一般情况下比较两个对象是比较它们的值是否一致,所以要进行重写;

转型:
 向上转型:小转大;父类引用指向子类对象;父类引用(类型变量)不能调用子类特有的属性或方法(就是子类新增的属性和方法);
 向下转型:大转小;父类类型的(引用,也可以说是对象)变量赋值给子类类型的变量,需要强制类型转换;子类类型的变量可以使用子类特有的属性和方法;
 可以使用 引用变量 instanceof 类名 的方式来判断该引用型变量所指向的对象是否属于该类或该类的子类;
 向下转型可能出现的类型转换错误情况:
  编译时报错:没有继承关系的两个类之间进行相互转换;
  运行时报错:向下转型时,父类的引用变量没有先引用子类对象,这种情况在编译不会报错,运行时抛出 java.lang.ClassCastException;

动态绑定:
1、解释:在运行期间(而非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法;
2、作用:增大程序的可扩展性;
3、通过多态实现程序的可扩展性;

构造方法:
1、作用:创建并初始化对象;
2、语法:
 方法名必须与类名相同;
 无返回类型;
 不能被static、final、synchronized、abstract和native修饰,只能被四种访问限制符修饰;
3、构造方法的重载:
 当通过new语句创建一个对象时,在不同的条件下,对象可能会有不同的初始化行为;可通过重载构造方法来表达对象的多种初始化行为;
 用this语句来调用其他构造方法时,必须遵守以下语法规则:
  必须是在本类的构造方法中调用;
  必须放在构造方法中的第一行;
  必须使用this关键字显式调用;
4、默认构造方法:
 分两种:隐含的默认构造方法;程序显式定义的默认构造方法(可以是任意的访问级别);
 如果在编写一个类时,没有显式编写一个构造器,系统就会提供一个默认的(无参的、无具体内容)构造器;这个默认的无参构造器将所有的实例域设置为默认值;如果在编写一个类时,自己显式编写了一个构造器,则系统不会再提供一个默认的无参构造器;如果此时还需要无参构造器,则必须手动再添加一个无参构造器;
5、子类调用父类的构造函数:
 子类的构造方法的过程中必须调用其父类的构造方法;
 如果子类的构造方法中没有显示调用父类的构造方法,则系统默认调用父类无参的构造方法;
 如果子类中构造方法中既没有显式调用父类的构造方法,而父类又没有无参的构造方法,则编译出错;
 用super语句来调用父类的构造方法时,必须遵守以下语法规则:
  必须在子类的构造方法中调用父类的构造方法;
  必须放在子类构造方法中的第一行;
  必须使用super关键字显式调用父类构造方法;
 在创建子类的对象时,Java虚拟机首先执行父类的构造方法,然后再执行子类的构造方法。在多级继承的情况下,将从继承树的最上层的父类开始,依次执行各个类的构造方法,这可以保证子类对象从所有直接或间接父类中继承的实例变量都被正确的初始化;
 子类的构造方法中必定会调用父类的构造方法(不管是隐式调用还是显式调用);
6、构造方法的作用域:
 构造方法只能通过以下方式被调用:
  当前类的其他构造方法通过this语句调用它;
  当前类的子类的构造方法通过super语句调用它;
  在程序中通过new语句调用它;
7、private修饰构造方法:
 当构造方法为private级别,意味着只能在当前类中访问它:在当前类的其他构造方法中可以通过this语句调用它,此外还可以在当前类的成员方法中通过new语句调用它;
 在以下场合之一,可以把类的所有构造方法都声明为private类型:
  在这个类中仅仅包含了一些供其他程序调用的静态方法,没有任何实例方法;
  禁止这个类被继承(但还是可以实例化);

final关键字:
1、作用:确保所修饰的这部分内容不能再被改变;
2、可以修饰的对象:类、方法、成员变量、局部变量(本地变量);
3、final修饰变量:
 凡是对成员变量或者本地变量声明为final的都叫作final变量;final变量经常和static关键字一起使用,作为常量;
 语法规则:
  final类型的变量必须显式地初始化,且只能被初始化一次;
  final成员变量必须在声明时或者在构造函数中被初始化,而不能在其它的地方被初始化;
  final成员变量在声明时初始化,声明和初始化必须同时(一起写)完成,不能分开(分成两条语句来写);但局部变量可以这样写;
4、final修饰方法:
 final修饰的方法不可以被子类的方法重写,也就是说子类是不能够存在和父类一模一样的方法;
5、final修饰类:
 final修饰的类不能被继承;
 Java中有许多类是final的,比如String, Interger以及其他包装类;
 final修饰的类,其成员变量可以为final,也可以为非final;其方法默认为final(方法被强制设为final,因为类不能被继承,所以方法也不会被重写);

接口:
1、作用:就是用来被继承的,被实现的;因此修饰符一般建议使用public或默认即可;不能使用private和protected修饰接口;
2、语法格式:
 是抽象方法和常量值的集合;
 静态常量:使用public static final修饰变量,可以不显式写出(默认加上)这三个修饰符;
 抽象方法:使用public abstract修饰方法,可以不显式写出(默认加上)这两个修饰符;
3、特性:
 接口可以多重实现;
 接口可以多重继承;
 可以使用 public static final(默认可以不显式写出)、仅 public、仅 final、仅 static 几种方式来修饰变量;
 可以使用 public abstract(默认可以不显式写出)、仅 abstract、仅 public、仅 default 几种方式来修饰方法;
4、接口的实现:
 当类实现接口的时候,类要实现接口中所有的方法;否则,类必须声明为抽象的类;
 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常;
 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型(一般都不会变,只添加方法体);
5、标记接口:
 标识接口是没有任何方法和属性的接口,它仅仅表明它的类属于一个特定的类型;简单形象的说就是给某个对象打个标记,使对象拥有某个或某些特权;
 标记接口主要用于以下两种目的:
  建立一个公共的父接口:可以使用一个标记接口来建立一组接口的父接口;
  向一个类添加数据类型:实现标记接口的类不需要定义任何接口方法,但是该类通过多态性变成一个接口类型;
6、接口与类的区别:
 接口不能用于实例化对象(也没有构造方法);
 接口中所有的方法必须是抽象方法;(这句话现在已经是错误的了)
 接口不能包含成员变量,除了static和final变量;(看似定义的是普通的成员变量,其实是final static 没有显式写出而已)
 接口支持多重继承;类只支持单继承;
7、接口与抽象类的区别:

抽象类:
1、介绍: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类;
2、作用:抽象类不能实例化对象,所以抽象类必须被继承,才能被使用(实现扩展和多态);
3、使用场景:
 在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些类如何实现这些方法;
 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随性;
4、抽象类的特性:
 包含抽象方法的类一定是(要声明为)抽象类;
 没有抽象方法的类也可以声明为抽象类;
 抽象类可以包含具体数据和具体方法(方法可以被实现);
 抽象类不能直接创建(实例化),可以定义引用变量(非抽象子类对象),即依靠子类来完成特定功能;
 继承抽象类的子类:
  如果仅实现基类部分的抽象方法,则子类也必须被声明为抽象类;
  如果实现基类所有的抽象方法,则子类不必被声明为抽象类;

一个类只能用下面三种修饰符来修饰:public  abstract  final ;

多态:
1、介绍:多态是同一个行为具有多个不同表现形式或形态的能力;多态性是对象多种表现形式的体现(要实现某种功能,不同的子类有不同的实现方式);
2、实现多态的三个必要条件:继承、重写、父类引用子类对象;
3、多态中涉及到的引用类型转换:向上转型和向下转型;

包:
1、 包声明应该在源文件的第一行;
2、每个源文件只能有一个包声明,这个文件中的每个类型都应用于它;
3、如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中;
4、在java源文件中import语句应位于package语句之后,所有类的定义之前,可以没有,也可以有多条;
5、如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略(不需要通过import语句引入);
6、通常,一个公司使用它互联网域名的颠倒形式来作为它的包名;

重写(Override):
1、作用: 如果子类对继承父类的方法不满意,就可以通过重写继承父类的方法来实现自己的需求;
2、语法规则:
 子类中方法的返回值类型、方法名、参数类型及个数及顺序都要与父类继承的方法相同;
 子类方法的访问权限不能比父类中被重写的方法的访问权限更高;
 满足以上两条才能叫重写;
3、注意事项:
 声明为final的方法不能被重写;
 声明为static的方法不能被重写,但是能够被再次声明(可以和父类静态方法一模一样,但两者没有关系,直接将父类继承来的静态方法隐藏掉了);
 构造方法不能被重写;
 如果不能继承一个方法,则不能重写这个方法;
 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法;
 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法;
 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常;但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以;
 子类可以通过super关键字调用父类的方法;

重载(Overload):
1、重载规则:
 在一个类里面,方法名字(必须)相同,而参数(必须)不同;返回类型和访问限定符可以相同也可以不同;
 被重载的方法可以声明新的或更广的检查异常;
 方法能够在同一个类中或者在一个子类中被重载;

重写和重载的比较:

局部变量不能加访问限定符;

内部类:
定义:定义在另一个类中的类;
使用内部类的原因:
 内部类方法可以访问该类(这里的该类应该指的是外部类)定义所在的作用域中的数据,包括私有的数据;
 内部类可以对同一个包中的其它类隐藏起来;
 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷;
语法总结:
 内部类既可以访问自身的数据域,也可以访问创建它的外部类对象的数据域;
 内部类的对象总有一个隐式引用,它指向了创建它的外部类对象;这个引用在内部类的定义中是不可见的;
 内部类不需要通过外部类的公有方法访问外部类的私有属性,可以直接访问;
内部类的分类:
 成员内部类:
 方法内部类(局部内部类):一开始是成员内部类,但这个内部类只在外部类的一个方法中使用过一次,这种情况下可以将此内部类定义在方法中,即方法内部类; 方法内部类不能使用public或private(protected 和 default也不行)访问限制符(只能使用abstract 或者 final)进行声明,它的作用域被限制在这个方法中; 优点:对外部世界可以完全的隐藏起来,只有外部类的这个方法可以访问它,其它任何类和任何方法都不知道它的存在;不仅能访问包含它们的外部类,还能访问局部变量,但这个局部变量必须被声明为final;
 静态内部类:
  优点(作用):只是为了把一个类隐藏在另一个类的内部,并不需要内部类引用外部类对象;为此,可以将内部类声明为static,以便取消产生的引用;
 匿名内部类:
  含义:只需要创建内部类的一个对象,不需要知道内部类的名字;
  前提:必须继承一个父类或实现一个接口;
  优点(作用):只能使用一次,它通常用来简化代码编写;
  应用:最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口;
  语法限制:
   不能有构造器,但可以把构造器参数传给超类的构造器;在内部类实现接口时,不能有任何构造器参数;
   匿名内部类可以在外部类中直接定义,也可以在外部类的方法中进行定义;

回调函数:
 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,
然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,
店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件;

方法里面定义变量的时候,要么不使用修饰符(包括访问限定符、static等修饰符),要么只能使用final修饰符;

posted @ 2018-02-20 22:14  kehuaihan  阅读(138)  评论(0编辑  收藏  举报