Java的特征
封装
- 特征:
- 该露的露,该藏的藏 一般把属性设置为私有(private)的,提供公共的方法(public)get/set实现对属性的存取
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
//set方法可以做一些安全性的验证
public void setAge(int age) {
if(age<0||age>120){
this.age = 3;
}else{
this.age = age;}
}
- 意义
- 提高的程序的安全性-,保护数据
- 隐藏代码的实现细节
- 统一接口(通过get/set)
- 提高系统的可维护性
- 高内聚,低耦合
继承
- 本质:对一批类的抽象(类是对一批对象的抽象),从而实现对现实世界更好的建模
- extends:子类是父类的扩展
- 只有单继承无多继承
- 父类和子类的关系: is a
- 在java中,所有的类都默认直接或间接继承Object类
- 子类可以继承父类的私有方法,但是没有访问权限
- 子类在new对象时,默认先调用父类的无参构造,如果要在子类无参构造中显示调用父类构造器,必须写在第一行
public Student() {
super();//必须写在第一行
System.out.println("子类构造器调用");
}
关键字super this
public class Student extends Person{
private String name="ls";
public void sayHello(String name){
System.out.println(name);//调用sayHello(x)实参x的值
System.out.println(this.name+"hello");//当前类属性name的值ls
System.out.println(super.name+"hello");//父类中的属性name值 zs
}
}
- 注意点:
- super调用父类的构造方法,必须在构造方法的第一行
- super只能出现在子类的方法或者构造方法中
- super、this不能同时调用构造方法(都只能出现在第一行
- 与 this的区别
- 代表的对象不同
- this:本身调用者这个对象
- super:代表父类对象的引用
- 前提
- tihs:没有继承也可以使用
- super:只能在继承条件下才可以使用
- 构造方法:
- this:本类的构造
- super:父类的构造
- 代表的对象不同
重写
子类的方法要和父类保持一致,但方法体不同
- 条件
- 只针对方法
- 方法名必须相同
- 参数列表必须相同
- public修饰非静态方法
- 前提:只存在于子父类之间,子类重写父类的方法
为什么需要重写? - 父类的功能子类不一定需要或不一定满足
不能重写的方法 - static 修饰的方法,属于类,不属于实例
- final 修饰的方法,常量
- private修饰的方法
多态
可以实现动态编译,可扩展性增强
同一个方法,可以根据发送对象的不同而采用多种不同的行为方式
一个对象的实际类型是固定的,但可以指向对象的引用的类型有多种
存在条件
- 有继承关系
- 子类重写父类方法
- 父类的引用指向子类
//一个对象的实际类型是确定的
new Person();
new Student();
//指向该对象的引用具有不确定性
Person s1=new Student();//Person 父类型:可以指向子类,但不能调用子类独有的方法
//父类的引用指向子类
Student s2=new Student();// Student 子类型:调用自己的方法以及 继承父类的方法
Object s3=new Student();
s1.sayHello();//子类重写了父类的方法,执行子类的该方法
s2.sayHello();
//对象能执行哪些方法主要看该对象左边的类型
//s1.study(); 执行错误
((Student) s1).study();
//s3.sayHello();错误:父类不能调用子类自己的方法
注意事项
- 多态是方法的多态,属性没有多态
- 父类和子类存在一种关系(is a)
- 存在的条件:继承关系,方法需要重新,当一个方法被重写,调用时只调用子类中重写的方法 父类引用指向子类的对象!
//父类
public class Person {
public String name="zs";
public static int age=18;
public void sayHello(){
System.out.println(name);
}
public static void go(){
System.out.println("父类的go方法"+age);
}
}
//子类
public class Student extends Person{
public String name="ls";
public static int age=20;
public void sayHello(){
System.out.println("子类"+name);
}
public static void go(){
System.out.println("子类的go方法"+age);
}
}
//测试
public static void main(String[] args) {
Student student=new Student();
System.out.println(student.name);//ls
System.out.println(student.age);//20
student.sayHello();//子类ls
System.out.println("============");
Person person=new Student();
System.out.println( person.name);//zs 无论编译还是运行,获取属性看=的左边边(无论静态还是非静态)
System.out.println(person.age);//18
person.sayHello();//子类ls 执行成员函数(非静态)编译看=左边,运行看=的右边
person.go();//父类的go方法18 执行静态函数无论编译还是运行看=的左边
}
instanceof 类型转换
System.out.println(A instanceof B):有关系(父子关系),编译通过,没关系编译不通过
如果有关系,其中A是类的引用,B是类
Object object=new Student();
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
Student student=new Student();
System.out.println(student instanceof Object);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Student);//true
// System.out.println(student instanceof Teacher);//编译不通过
//System.out.println(student instanceof String);//编译不通过
注意:
- 父类的引用指向子类的对象
- 把子类转换成父类,向上转型,不用强制转换,引用时无法使用子类的独特方法
Student student=new Student();
Person p1=student;//子类转父类
//p1.study();//丢失了子类原有的独特方法,即无法使用子类的独有的study
- 把父类转换成子类,向下转型需要强制转换
Person p=new Person();
Student s= (Student) p;//父类转子类,强制转,丢失了父类被子类所重写的方法