面对对象的三大特征是封装,继承和多态。
1. 封装
总结:属性私有,get/set
在类中先将属性使用修饰符 private创建好
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;//年龄
修饰符 private 是私有的,使用后,主程序无法通过new一个对象s1后,通过s1.name调用该属性。这时,我们就需要在类里面提供一些可以操作这些属性的方法。
//get获得这个数据
public String getName(){
return this.name;
}
//set给这个数据设置值
public void setName(String name){
this.name = name;
}
这就是 get/set 操作,可以使用快捷键 Alt+Insert 生成。
一般可以在set方法内设置一些判断。
public int getAge(){
return age;
}
public void setAge(int age){
if (age>120 || age<0 ){//不合法的
this.age = 3;
}else {
this.age = age;
}
}
创建好方法后,主函数便可以调用
Student s1 = new Student();
s1.setName("开南");
System.out.println(s1.getName());
s1.setAge(22);
System.out.println(s1.getAge());
同样,也是需要先创建一个对象,这时,可以通过对象.方法的方式调用,即 s1.setName(“开南”); 参数与方法保持一致,即创建时有(无)参则调用时保持有(无)参。
以上操作就是封装,这样别人在使用封装后的类时,只可以改变参数,把并不能对程序,代码进行相关的操作,这样可以提高程序的安全性,保护数据,以及隐藏代码的实现细节;还统一了接口,使用 get/set;使得系统的可维护性增加了。
2.继承
继承使用的关键字是 extends
A继承B
public class A extends B{
}
此时A为子类,B为父类,子类继承父类,就会有父类的全部方法。Java中只有单继承,没有多继承(换句话说就是儿子只能有一个爹,爹可以有多个儿子)。
在Java中,所有的类都直接或者间接的继承 Object
Super与This
this指的是当前类,super所指代的是父类
this.print();
super.print();
即 this.print(); 调用的是当前类的 print()方法,而 super.print(); 则是调用父类中的 print()方法。
注意点:私有的不能被继承!!当出现 Private 修饰符时,其所在的部分不被继承。
子类的无参构造会调用父类的无参构造,且父类的构造器必须在子类构造器的第一行!!!
**方法重写:**重写是方法的重写,和属性无关!
以 A、B为例,
public class A extends B{
public static void test(){
System.out.println("A-->test()");
}
}
A继承B,且有一个 text() 方法;
public class B {
public static void test(){
System.out.println("B-->test()");
}
}
B 同样也有一个 text() 方法;
此时,主函数
A a = new A();
a.test();
//父类的引用b指向了子类
B b = new A();
b.test();
存在继承关系,父类的引用可以指向子类,即 B b = new A();
输出的结果为A-->test() B-->test()
。
此时我们发现,静态方法的调用只和左边,定义的数据类型有关。
当我们把方法中的 static 去掉,会出现注解override(有功能的注释),override 即重写。
public class A extends B{
public void test(){
System.out.println("A-->test()");
}
}
public class B {
public void test(){
System.out.println("B-->test()");
}
}
主函数不变,此时输出的结果为A-->test() A-->test()
,
由此可知,重写存在于非静态方法,且是 public 修饰的方法。
哪些方法不能被重写?
- static 方法 ,属于类,不属于实例;
- final 常量;
- private 方法,私有的。
3.多态
我们知道,我们在new一个对象时,new什么就是什么,
new Student();
new Person();
即一个对象的实际类型是确定的,但可以指向的引用类型就不确定了:父类的引用指向子类
Person s2 = new Student();
这里 Student 是继承 Person 的。
1、子类能调用的方法都是自己的或继承父类的;
2、父类可以指向子类,但不能调用子类独有的方法;
3、子类重写了父类的方法,执行子类的方法;
4、子类独有的方法,父类无法调用;
5、对象能执行那些方法,主要看对象左边的类型,和右边关系不大。
多态注意事项:
附加内容:
instanceof 用来判断是否存在继承的关系
//Object > String
//Object > Person > Student
//Object > Person > Teacher
Object object = new Student();
System.out.println(object instanceof Student);//ture
System.out.println(object instanceof Person);//ture
System.out.println(object instanceof Object);//ture
System.out.println(object instanceof Teacher);//False
System.out.println(object instanceof String);//False
System.out.println("============");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//ture
System.out.println(person instanceof Object);//ture
System.out.println(person instanceof Teacher);//False
//System.out.println(person instanceof String);//编译报错
System.out.println("============");
Student student = new Student();
System.out.println(student instanceof Student);//ture
System.out.println(student instanceof Person);//ture
System.out.println(student instanceof Object);//ture
//System.out.println(student instanceof Teacher);//编译报错
//System.out.println(student instanceof String);//编译报错
*/
我们可以通过类型的转换来调用一些原本无法调用的方法。
//类型之间的转换 高——————>低
//高 低
Person student = new Student();
//student将这个对象(当前是 Person 类型)转换成Student类型,我们就可以使用Student类型的方法了
((Student)student).go();
//子类转换成父类可能丢失本来的一些方法
Student student1 = new Student();
student1.go();
Person person = student1;
static 详解
//第二个执行
{
System.out.println("匿名代码块");
}
//第一个执行 且只执行一次
static {
System.out.println("静态代码块");
}
//第三个执行
public Person(){
System.out.println("构造方法");
}
static 的优先级比较高。
public class Student {
private static int age;//静态变量 多线程
private double score;//非静态变量
public void run(){
go();//非静态方法可以直接调用静态方法
}
public static void go(){
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(Student.age);
System.out.println(s1.age);
System.out.println(s1.score);
go();//静态方法可直接使用
new Student().run();//非静态方法需要通过new一个对象去使用
}