Java基础知识(1)
一、面向对象
-
面向对象的基本特征
封装、继承、多态
-
封装
就是隐藏对象的属性和实现细节,仅对外暴露公共的访问方式。 -
继承
就是当子类继承父类,作为一种特殊的父类,将直接获得父类的非private的属性和方法(还有构造方法也是不能被继承的),让类与类之间产生了关联,提供了多态的前提条件,同时它是面向对象实现软件复用的重要手段。 -
多态
就是子类对象可以赋值给父类变量,但运行时依然表现出子类的行为特征,也就是说,同一个类型的对象在执行同一个方法时,可以表现出多种行为特征。因为在程序运行时才确定到具体的类,这就能让引用变量绑定到不同的类型实现上,从而导致引用调用的方法发生改变,而表现出不同的行为特征。(List list = new ArrayList())
良好的封装具有的优点
- 隐藏信息和实现细节,提高安全性
- 良好的封装可以减少耦合性,提高复用性
- 对类内部结构可以随意修改,只要保证公有接口始终返回正确的结果即可。
实现多态的前提条件
- 继承
- 重写ss(要有方法的重写)
- 向上转型(父类的引用指向子类的对象
-
-
访问权限
- private 同一个类
- 默认(default) 同一个类 同一个包
- protected 同一个类 同一个包 不同包的子类
- public 同一个类 同一个包 不同包的子类 不同包非子类
-
六大设计原则
- 单一职责原则
一个类只负责一个功能领域中的相应职责 - 开闭原则
对象应该对于扩展是开放的,对于修改是封闭的。 - 里氏替换原则
所有引用基类的地方必须能透明地使用其子类的对象。 - 依赖倒置原则
高层模块不依赖低层模块,两者应该依赖其对象;抽象不应该依赖细节;细节应该依赖抽象。 - 接口隔离原则
类间的依赖关系应该建立在最小的接口上。 - 迪米特原则(最少知识原则)
也称最少知识原则,一个对象对其他对象有最少的了解,尽可能少的与其他实体发生相互作用
- 单一职责原则
-
重写与重载
重载
重载,发生在同一个类中,方法名相同、参数列表不同(参数类型不同,个数不同,顺序不同),与返回值和访问修饰符无关。重写
重写,就是具体的实现类对于父类的该方法实现的不满意,需要自己写一个符合自己要求的方法,发生在父子类中,方法名、参数列表必须相同,如果父类方法访问修饰符为private则子类中就不是重写(返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则))。区别
-
方法的重载和重写都是实现多态的方式,区别在于重载实现的是编译时多态性,重写实现的是运行时多态性。
就要提到java虚拟机中的"分派"一词,分派分为静态分派和动态分派: -
虚拟机层面
就要提到Java虚拟机中的"分派"一词,分派分为静态分派和动态分派:
静态分派,依赖静态类型来决定方法执行版本的分派动作,静态分派的最典型应用表现就是方法的重载
动态分派,依赖实际类型来决定方法执行版本的分派动作,动态分派的最典型应用表现就是方法的重写虚拟机在重载时是通过参数的静态类型而不是实际类型作为判断依据的,由于静态类型在编译期可知,所以在编译阶段,Javac编译器就会根据参数的静态类型来决定会使用哪一个重载版本。
重写时,我们通过代码的字节码可以找到invokevirtual指令,而该指令运行时解析的第一步就是找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C;正是invokevirtual指令执行的第一步就是在运行期间确定接收者的类型,除了解析以外(所以调用中的invokevirtual指令并不是把常量池中方法的符号引用解析到直接引用就直接结束),还会根据方法接收者的实际类型来选择方法版本。
-
重载的方法能否根据返回类型进行区分?
不能,Java调用方法是可以忽略方法的返回值的,如果调用会不知道哪个方法,所有不能使用方法的返回值类型来作为区分方法重载的依据
-
-
接口与抽象类的区别
抽象类
抽象类,如果一个类含有抽象方法,那么这个类就是抽象类,它是对事物的抽象。抽象类必须在类前使用abstract关键字修饰。此外,抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。接口
在软件工程中,接口泛指供别人调用的方法或者函数。它是对行为的抽象,接口中可以含有变量和方法,但接口中变量被隐式的指定为(public static final),方法被隐式的指定为(public abstract)方法,并且接口中的所有方法不能有具体的实现,也就是说都是抽象方法,是一种极度抽象的类型。区别
-
语法层面的区别
- 抽象类除了抽象方法,还可以有普通成员方法,可以提供成员方法的实现细节;而接口中只能存在(public abstract)的方法
- 抽象类中成员变量可以是各种类型的;而接口中的成员变量只能是(public static final)类型的。
- 抽象类可以有静态代码块和静态方法;而接口中不能含有;
- 一个类只能继承一个抽象类,而一个类可以实现多个接口
- 抽象类要被子类继承extend,而接口是要被实现implement
-
设计层面的区别
-
抽象类是对一种事物的抽象,即对类的抽象;而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括(属性、行为),但接口却是对类的局部(也就是行为)进行抽象。
比如说,飞机和鸟时不同类的事物,但它们都有一个共性(飞),不同种类的鸟都直接继承鸟这个类,因为都属于一种事物,同样不同型号的飞机都直接继承飞机这个类,然后可以根据自己的需要实现fly(飞)这个接口。从这里可以看出继承是一个"是不是"的关系,而接口实现则是"有没有"的关系。
-
抽象类作为很多子类的父类,它是一种模板式设计。
接口是一种行为规范,是辐射式设计。
也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,继承的子类可以根据具体需要进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
-
两者的选择原则
行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能。 -