Java面向对象编程

面向对象的特征:封装,继承和多态。

封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。原则是将不需要对外提供的内容都隐藏起来,把属性隐藏,提供公共方法对其访问。

   

类和对象之间的关系

类是一组相关的属性和行为的集合。

对象是该类事物的具体体现。

例如学生是一个类,班长就是一个具体的对象。

   

一个类中可以包含成员变量(表示类的属性)和成员方法(表示类的行为)。

Java中,类的定义,创建一个具体类的方法如下:

   

类中的成员变量和局部变量

成员变量和局部变量的区别

在类中的位置不同,成员变量在类中的方法外声明.

局部变量在方法内声明

   

成员变量存在于堆内存,局部变量存在于栈内存

   

成员变量是随着对象的创建而存在,随着对象的消失而消失。 局部变量随着方法的调用而存在,随着方法的消失而消失。

   

类中的成员变量在未初始化的情况下是有默认值的,但类函数中局部变量必须进行初始化。如下图,方法中的局部变量未初始化会报错。

   

类中局部变量的名称和成员变量的名称可以是同名字的,在使用的时候,采用的是就近原则。

   

当一个方法的参数是类类型,则此参数是引用类型,需要传递该类的对象。在这一点和数组名差不多,传递的实际是对象的地址,形式参数的改变会直接影响实际参数。

   

匿名对象,就是没有名字的对象,可以应用于只需调用一次的情况。

   

private关键字

私有的,被修饰的成员变量和方法只能在本类中被使用,无法被类以外语句调用。

   

this关键字

可以代表当前类的对象的引用,可以访问当前对象内的成员变量和方法。

   

构造方法

构造方法的格式:

方法名和类名相同

没有返回值类型,void都没有

没有具体的返回值, 即不能有return语句

   

每个类中默认会有一个和类同名的方法。如果用户不创建构造方法,系统会给出默认的构造方法. 可以用反编译工具查看.

   

构造方法在创建对象的时候会调用,可利用此函数对成员变量进行赋值。

   

构造方法可以重载,系统默认调用一个无参数的空方法,如果在类中有定义,则调用类中的构造方法。

   

构造方法支持重载,在类中可以实现无参数和有参数的构造方法。

   

类的初始化过程

Student s = new Student(); 在内存中做了哪些事情?

加载Student.class文件进入内存

在栈内存为 s 开辟空间

在堆内存为学生对象开辟空间

对学生对象的成员变量进行默认初始化

对学生对象的成员变量进行显示初始化

通过构造方法对学生对象的成员变量赋值

学生对象初始化完毕,把学生对象地址赋值给s变量

static关键字

static可以修饰成员变量,也可以修饰成员方法。

被static修饰的成员或者变量,其数值被此类所有的对象共享。

其随着类的加载而加载,优先于对象存在。

static修饰的成员变量,可以直接利用类(非所创建的对象)的名字去访问。

   

在静态方法中是没有this关键字的,因为静态变量和方法是随着类的加载而加载,this随着对象的创建而存在。

静态方法只能访问静态的成员变量和静态的成员方法。

非静态的方法可以访问静态和非静态变量和方法。

   

静态变量和成员变量的区别,

所属不同,静态变量属于类,成员变量属于对象。

内存中的位置不同。静态变量存储于方法区的静态区,成员变量存储于堆内存。

内存中出现的时间不同。静态变量随着类的加载而加载,成员变量随着对象的创建而存在。

调用不同。静态变量可以通过类名调用,也可以通过对象调用,成员变量只能通过对象名调用。

   

主函数的方法 public static void main(String[] args) {}

为什么主函数的名字是静态的,因为虚拟机不用新建此对象,直接可以调用类名.main即可。

   

制作帮助文档

通过在代码中按照javadoc的格式写注释,可以自动生成帮助文档.

eclipse支持自动导出帮助文档, export->java->javadoc 指定javadoc.exe(jdk\bin的目录下,未安装JDK,需要安装)的路径.

   

同一个包下的类可以直接被使用,不需要被导入。

   

工具类对象定义方法

通过将构造方法私有(private),外界就不能再创建对象了,可以直接用class名字去访问static

所谓的工具类指的是,此类定义好了一些常用的方法,不需要别人去创建对象,而是直接去使用其内部的函数。例如math.xxx

   

代码块的定义(使用{}括起来的代码)

局部代码块,在方法中出现;限定变量的生命周期。

   

构造代码块,在类中方法外出现;用{}括起来的代码。每次调用构造的时候,即创建对象的时候都会执行,并 且在构造方法之前执行。在类中是无法执行单独语句的,所有的语句必须在方法中或者在{}中。

   

静态代码块,在类中方法外出现;在{}前用static语句修饰。用于给类进行初始化,在加载的时候会执行,且只执行一次。

   

静态代码块,构造代码块,构造方法的执行顺序。

静态代码块(类加载的时候会执行一次) -> 构造代码块(每次调用构造方法都执行,即每次创建新对象的时候) - 构造方法

   

下图为测试代码,根据测试结果可以分析,类在第一次调用的时候会加载,静态代码块会在第一次创建对象的时候执行一次。

   

类的继承

当多个类存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需在定义属性和行为,只要继承那个类即可。

Java中可使用extends关键字描述继承关系。

   

Java中继承的特点

一个类只能有一个父类,不支持多继承

java支持多层继承

   

继承的注意事项,

子类只能继承父类所有的非私有的成员(成员方法和成员变量),即被private修饰的无法继承。

子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。

不要为了部分功能而去继承。

   

什么时候用继承呢?

继承其实体现的是一种关系: "is a "关系

例如 student和teacher可以继承person。

苹果,香蕉和橘子可以继承水果。即子类应该是父类的一种。

   

继承中成员变量的关系

如果子类中的成员变量和父类中的成员变量名字不一样,子类可以直接使用父类的成员变量。

如果名字一样,则可以利用super关键字可以访问父类成员变量。super相当于父类的引用。

   

superthis的用法

this(…); 和 super(…); 可以调用本地和父类的构造方法,…表示方法的参数。

子类每一个构造方法的第一条语句默认都是super();意为调用父类的构造方法。

thissuper还可以用于调用变量和方法。

   

继承中构造方法的关系:

在创建子类时,父类会先进行初始化,其构造方法会先执行一次。

   

子类构造方法执行前默认执行父类的无参数方法(如果存在多个构造方法的话),见下图测试程序。

   

一个类以及其父类的静态代码块,构造代码块,构造方法的执行次序分析

我们已经知道,静态代码块>构造代码块>构造方法,而静态的内容是随着类的加载而加载。静态代码块的内容会优先执行,程序在创建子类时,会先创建父类,因为子类有可能会用到父类的成员变量以及方法。

   

所以先执行父类的静态代码块,在执行子类的静态代码块。

然后执行父类的构造代码块和构造方法(优先访问无参方法),再执行子类的构造代码块和构造方法。

其测试结果如下图:

   

如果在创建子类的时候想执行父类的带参的构造方法,则需要调用super函数并且传递相应参数。注意,super需要放在第一条语句上,否则会执行多次父类的构造方法。

   

继承中成员方法的关系

如果子类中的方法和父类中的方法定义一样,先优先使用子类的(方法重写),如子类没有则使用父类的。

   

方法重写的应用,

当子类想在父类对应的方法添加一些功能时,子类可以重写该方法。

在子类函数中可以调用super.函数名调用父函数。

   

方法重写的注意事项,

私有方法不能被重写,因为父类私有方法,子类无法继承。

   

方法重写和方法重载的区别

方法重写,在子类中出现和父类一模一样的方法声明的现象。

方法重载,在同一个类中出现的方法名相同,参数列表不同的现象。

   

方法重载可以改变返回值的类型,因为它和返回值类型无关。

   

final关键字,可以修饰类,方法和变量。

final修饰的类,不能被继承。

final修饰的方法,不能被重写。

final修饰的变量,不能被重新赋值。

   

final修饰的基本类型,值不能被改变。

final修饰的引用类型,是地址值不能被改变。

   

final修饰变量的初始化时机

被final修饰的变量只能赋值一次。

在构造方法结束以前应完成初始值。

   

需要总结一下final, static , 和static final的区别

   

多态,同一个对象,在不同时刻表现出不同的状态。

多态的前提:

要有继承关系。

要有方法重写。

要有父类引用指向子类对象。(父类 f = new 子类();)

   

多态的分类:

具体类多态

抽象类多态

接口多态

   

多态中成员访问特点:

成员变量, 编译看左边,运行看左边。

构造方法,创建子类对象的时候,访问父类的构造方法。

成员方法,编译看左边,运行看右边。

静态方法,编译看左边,运行看左边。 // 左边和右边是指定义语句的左边父类还是右边子类。

即变量用父类的,方法用子类的。所以使用多态的前提,父类和子类必须有同名的成员变量和方法。

   

多态的应用

在创建工具类应用时,形参可以用父类,传递的时候传的是子类,程序仍然会执行对应子类的方法。

   

多态的弊端

多态无法使用子类的特有功能。

   

多态如何使用子类的特有功能?

通过将父类的引用强制转换为子类的引用可以使用。

对象间的转型问题,

向上转型, Fu f = new Zi();

向下转型,Zi z =(Zi)f;

   

多态中子类之间无法相互转换。

子类和父类之间转换。

   

抽象类

抽象类的格式,abstract class 类名{}

抽象类的特点:

抽象类和抽象方法必须用abstract关键字修饰,抽象方法没有代码块,方法为空。

抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类。

抽象类不能实例化,因为它不是具体的。抽象类有构造方法,但是不能实例化,构造方法可用于子类访问父类数据的初始化。

如果未写抽象方法,抽象类的子类必须也是一个抽象类。重写所有的抽象方法,这个时候子类是一个具体的类。

抽象类的实例化是靠具体的子类实现的,是以多态的方式。例如 Animal a = new Cat();

   

抽象类的成员特点,

成员变量,既可以是变量,也可以是常量。

构造方法,有。用于子类访问父类数据的初始化。

成员方法,既可以是抽象的,也可以是非抽象的。

抽象类的成员方法特性,

抽象方法 强制要求子类做的事情

非抽象方法 子类继承的事情,提高代码复用性。

   

abstract不能和privatefinalstatic关键字共存。

   

抽象类和普通类的区别,抽象类由于abstract特性,不能被直接创建对象,且被修饰的方法必须重新写,在一定程度上有安全的作用。

   

接口类

类的特点:

a, 接口用关键字interface表示

interface 接口名 {}

b, 类实现接口用implements表示

class 类名 implements 接口名 {}

c, 接口不能实例化

接口可以按照多态的方式实例化。

d, 接口的子类

可以是抽象类,但意义不大。

可以是具体类,要重写接口中的所有抽象方法。

   

接口成员特点

成员变量只能是常量,并且是静态的。默认的修饰符为 public static final

接口没有构造方法。

成员方法只能是抽象方法,默认的修饰符为public abstract

所有的类都默认继承自一个类: object。所以子类的构造方法会访问object的构造方法。

   

类与类之间关系: 继承关系,只能单继承(只能继承一个父类),可以多层继承。

类与接口的关系: 实现关系,可以单实现,也可以多实现。并且还可以在继承一个类的同时实现多个接口。

接口与接口的关系:继承关系,可以单继承,也可以多继承。

   

抽象类和接口的区别

成员区别:

抽象类:变量,常量;有抽象方法;有抽象方法,非抽象方法

接口: 常量;抽象方法;

关系区别

类与类继承:单继承。

类与接口实现,但实现,多实现。

接口与接口继承,单继承和多继承。

设计理念区别

抽象类被继承体现的是:"is a "的关系。抽象类定义的是该继承体系的共性功能。

接口被实现体现的是,"like a "的关系。接口中定义的是该继承体系的拓展功能。

   

形式参数和返回值的问题

形式参数可以是基本类型和引用类型,

所创建的对象可以作为参数传递。下图是以普通类作为形参的赋值方法;

下图是以abstract class作为形参的赋值方法

如果以接口为形参,则需要传递对接口的实现的对象,如下图

   

返回值类型可以是基本类型和引用类型

普通类作为返回参数时,实际返回的为一个对象。

当抽象类作为返回值时,返回的是该抽象类的子类对象。

当接口作为返回值类型时,返回的是该接口实现的对象。

   

链式编程

每次调用完毕方法后,返回的是一个对象。

   

包的定义

package 包名;

多级分包,分开即可。

   

注释事项:

package语句必须是程序的第一条可执行的代码。

package语句在一个Java文件中只能有一个。

如果没有package,默认表示无名包。

   

如果包不属于当前的文件,需要导入,

导入的格式为 import packagename.class名

   

权限修饰符

  

public

protected

默认

private

同一类中

同一包,子类,其他类

  

不同包,子类

  

  

不同包,其他类

  

  

  

   

内部类的特点

内部类可以直接访问外部类的成员,包括私有。

外部类要访问内部类的成员,必须创建对象。

   

按照内部类的定义的位置不同,可以分为成员内部类和局部内部类。

   

如何访问成员内部类

外部类名.内部类名 对象名 = 外部类对象.内部类对象;

   

成员内部类的修饰符,可以被privatestatic修饰

   

内部类访问数据的方式

局部内部类

匿名内部类的定义以及使用方法

前提:存在一个类或者接口

这里的类可以是具体类也可以是抽象类。

   

匿名对象中含有多个方法时的调用方法,可以利用多态,把匿名对象赋值给父类

在开发中,匿名内类也经常作为方法的参数进行传递,匿名类适用于仅仅使用一次的情况.

   

匿名内部类面试题

按照要求,补齐代码

要求在控制台输出"HelloWorld"

   

   

补齐后的代码

   

猜你喜欢

转载自www.cnblogs.com/pecar/p/8966947.html