面向对象
方法的重写
方法的重载 Overload
方法的重写 Override
共同点:都是方法的特性
不同:
重载的三个条件:
同一个方法内
方法名相同
参数列表|方法签名不同
重写的三个条件:
不同的方法内
继承关系|实现关系
方法签名相同
调用:
如果子类中存在方法的重写,当通过子类对象调用的时候,会调用子类中重写的方法,会对父类方法进行屏蔽
作用:
当子类从父类中继承了某一个方法,方法满意,方法的实现|方法体不满意的时候,就可以在子类中重现实现方法,重现定义方法体,重写方法
检查是否为重新方法:
1.在方法的左侧行首存在o↑标识
2.使用一个逐渐强制检查当前方法是否为一个重写方法@Override
方法重写的具体要求:
1.== 子类中重写方法,方法签名相等
2.<= 方法的返回值类型为基本数据类型时
要求被重写的方法和重写的方法返回值类型完全一致
方法的返回值类型为引用数据类型时
子类中重写方法的返回值类型小于等于父类中被重写方法的返回值类型
3.>= 子类中重写方法的权限修饰符大于等于父类中被重写方法的权限修饰符
注意:
1.被private修饰的方法不能被重写
2.被final修饰的方法不能被重写
3.静态方法不能被重写
当子类中出现和父类静态方法同名的方法,要求子类中的这个同名方法也要被static修饰
package com.xxx.demo;
public class OverrideDemo {
private int a;
private int b;
private static int c;
private static int d;
public OverrideDemo(){
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public static int getC() {
return c;
}
public static void setC(int c) {
OverrideDemo.c = c;
}
public static int getD() {
return d;
}
public static void setD(int d) {
OverrideDemo.d = d;
}
//方法签名相同,返回值为基本数据类型,返回值类型一致,权限修饰符为default
int getMax(){
if(a>b){
return a;
}else{
return b;
}
}
//方法被static修饰
public static int getMin(){
if(c>d){
return d;
}else{
return c;
}
}
}
package com.xxx.demo;
public class OverrideTest extends OverrideDemo{
public OverrideTest(){
}
//方法签名相同,返回值为基本数据类型,返回值类型一致,权限修饰符public大于父类中的default
@Override //使用注解强制检测该方法是否为重写方法
public int getMax(){
int max;
max = getA()>getB()?getA():getB();
return max;
}
//父类方法被static修饰,子类方法出现同名方法需要方法也被static修饰
//@Override //因为静态方法不能被重写,所以无法使用注解强制检查
public static int getMin(){
int max;
max = getC()>getD()?getD():getC();
return max;
}
}
super关键字
指代父类对象,可以通过super调用子类对象中的父类对象,但是不代表super存储了父类对象的地址,不能直接输出super
1.在子类构造器的首行,调用父类中的构造器
super(参数列表);
所以构造器中只能调用一个构造器,一个this(参数列表);或者一个super(参数列表);
在子父类继承的关系下,创建子类对象的时候,先父类后子类,父类对象在子类对象内存空间中
如果在子类构造器的首行没有显式调用父类构造器,默认调用父类空构造
2.区分子父类中同名成员问题
在子类中使用super指代子类内存空间中的父类对象
默认就近原则
通过super.父类成员;来调用父类成员
在静态方法中不能使用this,super关键字
package com.xxx.demo;
public class SuperDemo {
public static void main(String[] args) {
new Police();
System.out.println("-----------------------------------------");
new Police(1);
}
}
class Person{
private String name;
private int age;
public Person() {
System.out.println("父类空构造被调用");
}
public Person(int a){
System.out.println("父类带参构造被调用");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void run(){
System.out.println(age+"岁的"+name+"正在奔跑");
}
}
class Police extends Person{
public Police() {
super(1);
//this(); 报错,因为调用其他构造方法需要在构造函数的首行
System.out.println("子类空构造被调用");
}
//默认调用父类空构造
public Police(int a){
System.out.println("子类带参构造被调用");
}
}
/*
输出:
父类带参构造被调用
子类空构造被调用
-----------------------------------------
父类空构造被调用
子类带参构造被调用
*/
区分局部,子类成员,父类成员同名问题
package com.xxx.demo;
public class DifferentDemo {
public static void main(String[] args) {
new DifferentZi().print();
}
}
class DifferentFu{
DifferentFu(){
}
public int a=10;
}
class DifferentZi extends DifferentFu{
DifferentZi(){
}
public int a=5;
public void print(){
int a =1;
//使用this.和super.区分子父类同名变量,不加this和super关键字的话默认就近原则
System.out.println(a+"-->"+this.a+"-->"+super.a);
}
}
final关键字
最终的,是成员修饰符,也可以修饰局部
被final修饰的变量为常量,不能被修改
被final修饰的方法不能被重写
被final修饰的类不能被继承–>太监类
package com.xxx.demo;
public class FinalDemo {
final int f=10;
public static void main(String[] args) {
//f = 20; 不能被修改
}
}
class FinalFu{
public FinalFu(){
}
public final void print(){
System.out.println("我是父类");
}
//可以被重载
public final void print(int a){
System.out.println("我是父类");
}
}
class FinalZi extends FinalFu{
public FinalZi(){
}
/*
被修饰的类不能被重写
public final void print(){
System.out.println("我是子类");
}
*/
}
final class Finaltest1{
}
//class Finaltest2 extends Finaltest1{} 不能继承被final修饰的FinalTest1类
Object类
是java中所有类的父亲
在Java中的所有类都会直接或者间接的继承自Object类
toString()
toString() 把对象数据以字符串的形式表示
直接打印一个对象的引用的时候,默认打印的是调用toString()方法的返回值,此时会返回对象在堆内存中的地址
需求:
在打印一个javabean类型对象的引用的时候,其实是想要了解这个对象的基本信息->成员变量的值
解决:
在子类中重写toString方法,因为打印对象引用时候默认会调用toString(),toString功能需要,实现不满意,就重写
package com.xxx.learn.tostringdemo;
public class ToStringDemo {
public static void main(String[] args) {
StudentInfo si = new StudentInfo("张三",20,10000,"高一三班");
//在子类中将toString()方法重写,直接打印引用时,调用的为子类中重写的toString()方法
System.out.println(si);
}
}
package com.xxx.learn.tostringdemo;
//所有的类都是Object的子类
public class UserInfo {
private String name;
private int age;
private int id;
public UserInfo(){
}
public UserInfo(String name,int age,int id){
this.name = name;
this.age = age;
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int id) {
this.id = id;
}
//重写Object中的toString()
@Override
public String toString(){
return "姓名:"+this.name+"\n年龄:"+this.age+"\n学号:"+this.id+"\n";
}
}
package com.xxx.learn.tostringdemo;
public class StudentInfo extends UserInfo{
private String classname;
public StudentInfo(){
}
public StudentInfo(String name,int age,int id,String classname){
super(name,age,id);
this.classname = classname;
}
//重写UserInfo中的toString()
@Override
public String toString(){
return super.toString()+"班级:"+this.classname;
}
}
equals()
== 可以比较所有数据类型的数据
基本数据类型->比较数值,引用数据类型->比较对象地址
equals() 只能比较引用数据类型的数据
比较两个数据是否相等 对象1.equals(对象2)
Object类中equals方法的实现->默认比较对象的地址,可以通过重写equals方法实现比较对象的内容
在使用String引用数据类型调用equals方法时,jdk已经将equals方法重写,实现了比较字符串中内容是否相等.
需求:
比较两个引用数据类型对象的时候,想要比较两个对象的所有成员变量的值是否都相等,而非比较对象地址
解决:子类中重写equals方法,将对象中属性的值赋值给局部String类型变量,通过字符串类中的equals方法比较每个String变量是否相等,来比较对象中的内容,非地址
package com.xxx.learn.tostringdemo;
public class UserInfo {
private String name;
private int age;
private int id;
public UserInfo(){
}
public UserInfo(String name,int age,int id){
this.name = name;
this.age = age;
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getId() {
return id;
}
public String toString(){
return "姓名:"+this.name+"\n年龄:"+this.age+"\n学号:"+this.id+"\n";
}
}
package com.xxx.learn.tostringdemo;
public class StudentInfo extends UserInfo{
private String className;
public StudentInfo(){
}
public StudentInfo(String name,int age,int id,String className){
super(name,age,id);
this.className = className;
}
public String getClassname() {
return className;
}
public String toString(){
return super.toString()+"班级:"+this.className;
}
//子类中重写equals方法,用来StudentInfo对象和其他对象比较
@Override
public boolean equals(Object obj){
if(this == obj){
return true;
}
//判断一个对象是否为一个类的实例
if(obj instanceof StudentInfo){
//如果是,就把它强制转换为StudentInfo类型,保证可以调用StudentInfo类中的方法
String name = ((StudentInfo) obj).getName();
String className = ((StudentInfo)obj).getClassname();
return (this.getName().equals(name) && this.getClassname().equals(className) && this.getAge() == ((StudentInfo)obj).getAge() && this.getId() == ((StudentInfo)obj).getId());
}
return false;
}
}
package com.xxx.learn.tostringdemo;
public class ToStringDemo {
public static void main(String[] args) {
StudentInfo si1 = new StudentInfo("张三",20,10000,"高一三班");
StudentInfo si2 = new StudentInfo("张",20,10000,"高一三班");
StudentInfo si3 = new StudentInfo("张三",20,10000,"高一三班");
System.out.println(si1);
System.out.println(si2);
System.out.println(si1.equals(si2));
System.out.println(si1.equals(si3));
}
}