介绍
概述:Inheritance把多个子类的相同属性提取到父类,子类继承并直接使用。
特点:单继承。
子类继承父类,可以得到(除构造方法外)父类的全部(包括私有)属性和方法,不能直接访问父类私有属性和方法,可以通过公共的setget方法访问。
Object类是顶级父类,所有类间接或者直接继承自它。
意味着所有的Java对象都拥有Object类的属性和方法。如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类。
注意:如果父类有有参构造方法,子类重写父类必须提供有参构造方法(或者父类再提供一个无参构造),子类有参构造的参数列表必须包含父类构造方法里的参数。
Eclipse使用Ctrl+T查看继承结构
示例:
package com.itcode.demo;
/**
* @author: 成都码到功成学员
* @Description: 继承
*/
// extends Object可以写可以不写,默认继承,Object类是顶级父类,所有类间接或者直接继承自它。
class TestFather /* extends Object */{
int id;
String name;
public void eat() {
System.out.println("吃饭");
}
}
class TestSon extends TestFather{
int age;
public TestSon() {
}
public TestSon(int age) {
//引用父类属性id,name
this.id = id;
this.name = name;
this.age = age;
}
public void sleep() {
eat();// 调用父类方法
System.out.println("睡觉");
}
}
public class TestExtend {
public static void main(String[] args) {
TestSon son = new TestSon();
son.sleep();// 直接输出吃饭睡觉
// 对象类型判断
System.out.println(son instanceof TestSon);// true
System.out.println(son instanceof TestFather);// true
System.out.println(son instanceof Object);// true
}
}
效果:
方法重写overwrite
概述:子类重写父类的方法,子类行为覆盖父类行为。重写是实现多态的必要条件。
要点:
1、“==”
: 方法名、形参列表(参数个数、参数类型、参数顺序)相同。
2、“≤”
:返回值类型(引用类型≤基本类型==)、异常类型,子类小于等于父类。
如图:
示例:
package com.itcode.demo;
/**
* @author: 成都码到功成学员
* @Description:
* overwrite方法重写
*/
class TestFather2 {
public void study() {
System.out.println("父类学习");
}
public TestFather2 stop() {
return new TestFather2();
}
}
class TestSon2 extends TestFather2{
public void study() {
System.out.println("子类学习");
}
public TestFather2 stop() {
// 返回值类型和异常类型,子类小于等于父类
// 可以
// return new TestFather2();
return new TestSon2();
// return new Object();// 报错
}
}
public class TestExtend2 {
public static void main(String[] args) {
TestSon2 son = new TestSon2();
son.study();// 输出子类学习,因为子类的study()已把父类的study()覆盖
}
}
重写与重载区别
toString()
概述:toString方法来自Object超类,我们可以类中重写它。
方法源码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
示例:
package com.itcode.demo;
/**
* @author: 成都码到功成学员
* @Description:
* toString();重写
*/
class TestTo {
int id;
String name;
/**
* @param id
* @param name
*/
public TestTo(int id, String name) {
this.id = id;
this.name = name;
}
// 重写toString();
@Override
public String toString() {
return "id=" + id + ", name=" + name;
}
}
public class TestToString {
public static void main(String[] args) {
System.out.println("TestToString类未重写toString时调用:");
System.out.println(" " + new TestToString().toString());
TestTo son = new TestTo(2, "成都码到功成");
System.out.println("TestTo类重写toString时调用:");
System.out.println(" " + son.toString());
}
}
效果:
==与equals
==比较基本(比较值)与引用数据类型(比较对象地址值),
equals方法比较引用数据类型
Object类的equals方法默认比较两个对象的hashcode值。
String类的equals方法比较字符串内容是否相等(常用)。
示例:
package com.itcode.demo;
/**
* @author: 成都码到功成学员
* @Description:
* ==与equals()
*/
class TestEs {
int id;
String name;
public TestEs() {
}
/**
* @param id
* @param name
*/
public TestEs(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
public class TestEquals {
public static void main(String[] args) {
System.out.println("Object类的equals()#########################################");
TestEs t1 = new TestEs();
TestEs t2 = new TestEs();
// 比较
System.out.println(t1 == t2);// false
System.out.println(t1.equals(t2));// false
TestEs t3 = new TestEs(12, "成都码到功成");
TestEs t4 = new TestEs(12, "成都码到功成");
TestEs t33 = t3;
// 比较
System.out.println(t3 == t4);// false
System.out.println(t33 == t3);// true
// true,是因为创建时会从方法区常量池中去找,没有就创建,有相同就直接引用。
System.out.println(t3.name == t4.name);// true
System.out.println(t3.equals(t4));// false
System.out.println("String类的equals();##########################################");
String s1 = new String();
String s2 = new String();
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true
String s3 = new String("成都码到功成");
String s33 = s3;
String s4 = new String("成都码到功成");
System.out.println(s33 == s3);// true
System.out.println(s33.equals(s3));// true
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true
String s5 = "成都码到功成";
String s6 = "成都码到功成";
System.out.println(s5 == s6);// true
System.out.println(s5.equals(s6));// true
System.out.println("基本类型只能==##########################################");
int i1 = 23;
int i2 = 23;
System.out.println(i1 == i2); // true
}
}
手写equals
重要
比如一个类Pig,两个属性姓名年龄
public Boolean equals(Object o){
if(this == o){return true;}
if(!(o intstanceof Pig)){return false;}
Big b = (Big)o;
return this.equals(b.name) && this.price == b.name;
}
super
super代表父类对象的引用,通过super关键字访问父类中被子类覆盖的方法或属性。
使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
如构造方法第一行代码无显式的调用super(...)或者this(...),Java默认会调用super(),调用父类无参构造方法。也可以调用有参构造方法,如super(id, name)。
属性/方法查找顺序
==比较基本(比较值
依次查找当前类至上溯每个父类一直到Object,无编译错误,有结束寻找。
构造方法调用顺序,先父后子。
示例
package com.itcode.demo;
/**
* @author: 成都码到功成学员
* @Description:
* 构造方法调用顺序
*/
class ExtFather {
public ExtFather() {
// super();// super();可以没有
System.out.println("父类无参构造");
}
}
class ExtSon extends ExtFather{
int age;
public ExtSon() {
// super();// super();可以没有,子类构造方法中不能出
System.out.println("子类无参构造");
}
public ExtSon(int age) {
this();//调用ExtSon2无参
}
}
public class TestExtend3 {
public static void main(String[] args) {
ExtSon son = new ExtSon();
}
}
效果: