java的三大特征
封装
封装:数据隐藏,定义对象的特征时,有必要决定这些特性的可见性,即哪些特性是对外部可见的,那些是用于表示内部状态而外部不可见的。
通常,应禁止直接访问一个对象中的数据,而应该通过操作接口来访问,这成为信息隐藏。
封装的过程
- 使用private修饰需要封装的成员变量。(私有)
- 提供一个公开的方法设置和访问私有的属性。
- 设置,set属性名();属性名首字母要大写
- 获取,get属性名();
例子
//set给属性赋值
//get获取属性值
public class Studnet{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
public class item{
public static void main(String[] args){
Student s = new Student();
s.setName("TOM");
System.out.println(s.getName());
}
}
- 提高了程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一用户的调用接口
- 提高程序的可维护性
- 便于调用者调用
良好的封装,便于修改代码,提高可维护性,可进行数据完整性检测,保证数据的有效性
继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。有利于提高代码的复用性
-
extends的意思是“扩展”。子类是父类的扩展。
-
java中类只有单继承,没有多继承。接口可以多继承!
-
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends表示。
-
子类和父类之间的关系,从理解上应该具有“is a”的关系
- dog is a animal
- student is a person
-
类和类之间是单继承,一个子类只能“直接”继承一个父类,一个父类可以被多个子类继承。
-
父类中的属性和方法都可以被子类继承
Object类
java中的任何对象(包括自定义和原生)都是Object类的子类。从API文档中,可以看到任何一个类最上层的父类都是Object(本身除外)。AnyClass is a Object
在Object类中,提供了一些方法被子类继承,在java中,任何一个对象都可以调用这些被继承过来的方法。(Object是AnyClass的父亲)
Super关键字
子类继承父类之后,在子类中可以使用this来表示访问或调用子类中的属性或方法,使用super就表示访问或调用父类中的属性或方法。
super的作用
- 访问父类中的属性
- 调用父类中的方法
- 调用父类中的构造器(子类构造器中默认会隐式的调用父类的无参构造器)
super注意点:
-
用super调用父类构造方法,必须是在构造方法中,且是第一个语句
-
super只能出现在子类的方法或者构造方法中
-
super和this不能够同时调用构造方法(因为都要求是构造方法的第一个语句)
-
只能在继承条件下才能使用。
方法重写
-
方法重写只存在于子类和父类(包括直接父类和间接父类)之间。在同一个类中方法只能被重载,不能被重写。
-
静态方法不能重写
- 父类的静态方法不能被子类重写为非静态方法
- 父类非静态方法不能被子类重写为静态方法
- 子类可以定义与父类的静态方法同名的静态方法(不是覆盖)
静态方法的调用只和变量(对象的引用)的声明类型有关
A类继承B类,A和B中都有相同的静态方法item B b = new A(); b.item(); //调用的是B类中的方法 A a = new B(); a.item(); //调用的是A类中的方法
-
私有方法不能被子类重写,子类继承父类后,不能直接访问父类的私有方法。
重写的语法
-
方法名必须相同
-
参数列表相同
-
访问控制修饰符可以被扩大,但是不能被缩小:public > protected > default > private
-
抛出异常类型的范围可以被缩小,但是不能被扩大:ClassNotFoundException > Exception*
-
返回类型可以相同,也可以不同,如果不同的话,子类重写后的方法返回类型必须是父类方法返回类型的子类型(数据类型没有明确的上下级关系)
例如:父类方法的返回类型可以是Animal,子类重写后的返回值可以是Animal也可以是Animal的子类Dog。
一般情况下,重写方法会和父类中的方法的声明完全保持一致,只有方法的实现不同。(也就是方法中的代码不一样)
多态
用于实现动态联编的,也就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。对于大型系统来说能提高系统的灵活性和扩展性。
多态可以不用关心某个对象的具体类型,就可以使用该对象的某些方法,从而实现更加灵活的编程,提高系统的可扩展性
允许不同类的对象对统一消息做出响应,就是同一消息可以根据发送对象的不同而采用多种不同的行为方式,相同类域的不同对象,调用相同的方法,执行的结果是不同的。
-
实例对象的实际类型是确定的
- new Student(); new Person();
-
可以指向对象的引用类型有很多
- 一个对象的实际类型虽然是确定的,但是这个对象所属的类型可能还有很多种
- Student继承了Person类
Student a = new Student(); Person b = new Student(); Object c = new Student();
Person和Object都是Student的父类,一个对象的实际类型是确定的。但是可以指向这个对象的引用类型,却是可以是这个对象实际类型的任意父类型。
-
一个父类引用可以指向它的任何一个子类对象
-
子类继承父类,调用方法,如果方法在子类中没有重写,就调用的是父类中的方法,否则就调用子类中重写之后的方法。
-
编译看左边,运行不一定看右边。
- java编译器在编译的时候会检测引用类型中含有指定的成员,如果没有就会报错。子类的成员是特有的,父类没有,所以他找不到。
- java中的方法调用,是运行时动态和对象绑定的,不到运行时候,是不知道哪个方法被调用的。
注意事项
- 多态是方法的多态,属性没有多态性。
- 编写程序时,如果想调用运行时类型的方法,只能进行类型转换。不然不能通过编译器的检查。但是如果两个毫无关联的类进行强制转换,则会报错:ClassCastException.
- 多态的存在要有3个必要条件:要有继承、要有方法的重写、父类引用指向子类对象。
以下三种类型的方法是没办法表现出多态特性的(因为不能被重写)
- static方法,被static修饰的方法是属于类的,不是属于实例的
- final方法,因为被final修饰的方法无法被子类重写
- private方法和protected方法,前者是因为被private修饰的方法对子类不可见,后者是因为尽管被protected修饰的方法可以被子类剪刀,也可以被子类重写,但是它是无法被外部所引用的,一个不能被外部引用的方法,则不能体现出多态性。
方法绑定
执行方法时,系统根据相关信息,能够执行内存地址中代表该方法的代码。
分为静态绑定和动态绑定。
静态绑定
在编译期完成,可以提高代码执行速度。
动态绑定
通过对象调用方法,采用动态绑定机制。这虽然让我们编程更加灵活,但是也降低了代码的执行效率。这也是JAVA比C/C++速度慢的主要因素之一。JAVA中出了final类,final方法、static方法,所有方法都是JVM在运行期间才会进行动态绑定的。
多态:编译时类型和运行时类型不一致,就会造成多态。