1.代码分析
我们先来看一段关于值交换的代码
class MyValue {//定义一个MyValue类(类名注意采取大驼峰形式) public int val; } public class Test { public static void swap(MyValue x,MyValue y) {//值交换 int temp = x.val; x.val = y.val; y.val = temp; } public static void main(String[] args) { MyValue val1 = new MyValue(); val1.val = 10; MyValue val2 = new MyValue(); val2.val = 20; swap(val1,val2); System.out.println(val1.val); System.out.println(val2.val); }
如果将public改成private,只需要利用get,set也可以进行值交换
注意:
get和set方法可以利用鼠标右键单击空白–》Generate–》getter and setter进行快捷调用
总结:
1.将Val1和 Val2的址传给x和y
2.x和y得到地址后,将里面的val值进行更改
3.Val1和 Val2所指对象的值也就进行了“交换”
2.多态
阐述:去完成某个行为,不同对象完成会产生不同的状态
2.1多态实现条件
继承 子类必须对父类中的方法进行重写 通过父类的引用调用重写的方法(向上转型)
class Person {//父类 public String name; public int age; public void sleep() { System.out.println(name + "正在睡觉"); } } class Student extends Person {//子类--》Student public void study() { System.out.println(name + "正在学习"); } } class Teacher extends Person {//子类--》Teacher public void teach() { System.out.println(name + "正在上课"); } }
2.1.1向上转型
3种表示方法
1.
注:向上转型只能访问父类自己的成员(属性/方法),不能访问子类的成员(属性/方法)
2.
3.
如果有小伙伴对第3种向上转型不理解,可以参考一下下面的截图
2.1.2重写
2.1.2.1重写需要满足的条件
方法名称相同 参数列表相同 返回值相同(如果不同,则必须构成父子类关系)
class Person { public String name; public int age; public void sleep() { System.out.println(name + "正在睡觉"); } } class Student extends Person { public void study() { System.out.println(name + "正在学习"); } public void sleep() { System.out.println(name + "正在教室睡觉"); }
此时的sleep方法就被重写了
2.1.2.2重写需要注意的点
private修饰的方法不能重写(访问权限受限制) static修饰的方法不能重写(这种方法属于类方法) 子类的访问修饰限定权限要>=父类的权限 被final修饰的方法是不能重写的(此时这个方法被称作密封方法)
此时调用sleep方法就会执行子类的sleep方法,这是因为发生了动态绑定
实现动态绑定需满足的条件: 向上转型 重写 通过父类引用调用这个父类和子类重写的方法
动态绑定:运行时才知道调用的方法
那么有没有静态绑定呢?
答案是有的。
我们可以把重载理解为静态绑定的一种
静态绑定:编译时就知道要调用的方法
重写和重载的区别
2.2多态实现
class Person { public String name; public int age; public void sleep() { System.out.println(name + "正在睡觉"); } } class Student extends Person { public void study() { System.out.println(name + "正在学习"); } @Override//重写的注解 public void sleep() { System.out.println(name + "正在教室睡觉"); } } class Teacher extends Person { public void sleep() { System.out.println(name + "正在办公室睡觉"); } public void teach() { System.out.println(name + "正在上课"); } } public class Test1 { public static void method(Person person) { person.sleep(); } public static void main(String[] args) { Person person1 = new Student(); person1.name = "张三"; method(person1); Person person2 = new Teacher(); person2.name = "法外狂徒"; method(person2); } }
上面的代码就是多态的简单实现
当父类引用的对象不同时,其表现出的行为是不一样的
2.3向下转型
上图即为向下转型
向下转型较为不安全
如下:
此段代码虽然编译器没有报错,但运行时就会产生错误
如果一定要使用向下转型,可以搭配 instanceof 关键字
如下:
2.4 避免在构造方法中调用重写的方法
class B { public B() { func(); } public void func() { System.out.println("B.func()"); } } class D extends B { private int num = 1; public D() { super(); } @Override public void func() { System.out.println("博哥真帅"); //System.out.println("D.func() " + num); } } public class Test3 { public static void main(String[] args) { D d = new D(); } }
打印结果:
我们可以看到,程序先去执行的是子类的func,而不是父类中的func
注意:当在构造方法中调用重写方法时,会先去执行子类的重写方法