面向对象特征之二:继承
为什么要有继承?
Ø多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
此处的多个类称为
子类,单独的这个类称为
父类(基类或超类)。
Ø继承的出现提高了代码的复用性。
Ø继承的出现让类与类之间产生了关系,提供了多态的前提。
关于继承的规则:
子类是对父类的“扩展”,明确子类不是父类的子集
java只支持单继承,一个父类可以有多个子类
方法的重写:子类继承父类后,若父类的方法对子类不适用,子类可以重写(overwrite)父类的方法
重写规则:1)要求子类方法的“返回值类型 方法名 (参数列表)”与父类方法一样
2)子类的方法的修饰符不能小于父类方法的修饰符
3)若父类方法抛异常,那么子类方法抛的异常类型不能比父类的大
4)子类的方法必须同为static或同为非static的
[面试题]方法的重载与重写的区别?
重载:“两同一不同”:同一个类,同一个方法名,不同的参数列表。注:方法的重载与方法的返回值无关。
>构造器是可以重载的
重写:(前提:在继承的基础上,子类在获取了父亲的构造以后,可以对父类中同名的方法进行“重构”)
方法的返回值,方法名,形参列表 形同;权限修饰符不小于父类的同名方法;子类方法的异常类型不大于父类的
两个方法要同为static或同为非static
在Java类中使用
super来调用父类中的指定操作:
Ø
super可用于访问父类中定义的属性
Ø
super可用于调用父类中定义的成员方法
Ø
super可用于在子类构造方法中调用父类的构造器
注意:
Ø尤其当子父类出现同名成员时,可以用super进行区分
Øsuper的追溯不仅限于直接父类
Øsuper和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
面向对象特征之三:多态性
在java中的体现:
1、方法的重载(overload)和重写(overwrite)。
2、对象的多态性:可以直接应用在抽象类和接口上。
//子类对象的多态性:父类的引用指向子类对象
Person p1=new Man();//向上转型
//虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法
p1.eat();
p1.walk();
Man m=(Man)p1;//向下转型,使用强转符,转换后可以调用man特有的方法
m.entertainment();
子类对象的多态性使用的前提:1、要有类的继承 2、要有子类对父类方法的重写
程序运行分为:编译状态和运行状态
对于多态性来说,编译时,“靠左边”,将此引用变量理解为父类的类型
运行时,“看右边”,关注与真正的对象的实体,子类的对象,执行的方法时子类重写的。
//多态使用的一个例子
public class TestAnimal {
public static void main(String[] args) {
TestAnimal t = new TestAnimal();
t.func(new Animal());
t.func(new Dog());
t.func(new Cat());
}
public void func(Animal a){//Animal a = new Dog();
a.eat();
a.jump();
if(a instanceof Dog){
Dog d = (Dog)a;
d.Wang();
}
if(a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse();
}
}
// public void func(Dog a){
// a.eat();
// a.jump();
// }
}
class Animal{
String name;
int age;
public void eat(){
System.out.println("进食");
}
public void jump(){
System.out.println("跳");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃食");
}
public void jump(){
System.out.println("狗急跳墙");
}
public void Wang(){
System.out.println("汪汪叫");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void jump(){
System.out.println("猫跳");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
子类对象的多态性,并不适用于属性,属性“看左边”
对Java对象的强制类型转换称为造型
Ø
从子类到父类的类型转换可以自动进行
Ø
从父类到子类的类型转换必须通过造型
(
强制类型转换
)
实现
Ø
无继承关系的引用类型间的转换是非法的
Ø在造型前可以使用instanceof操作符测试一个对象的类型
Object类是所有Java类的根父类
==操作符与equals方法比较
//==
1、基本数据类型:根据基本数据类型的值判断是否相同。相同返回true
注:两端数据类型可以不同,在不同的情况下,也可以返回true
2、引用数据类型,比较引用数据类型变量的地址值是否相等。
//equals();
1、只能处理引用类型变量
2、在Object类,发现equals()仍然比较的是两个引用变量的地址值是否相等
3、像String包装类 FIle类 Date类 这些重写Object类的equals()方法,比较的是“实体内容”是否完全相同
String类的内存解析
Person p1 = new Person("AA",12);
Person p2 = new Person("AA",12);
System.out.println(p1 == p2);//false
System.out.println(p1.equals(p2));//true
//关于String类
String str1 = "AA";
String str2 = "AA";
String str3 = new String("AA");
System.out.println(str1 == str2);//true
System.out.println(str1.equals(str2));//true
System.out.println(str1 == str3);//false
System.out.println(str1.equals(str3));//true
System.out.println(p1.name == p2.name);//true
Object类里的方法
toString()方法
1、当打印一个对象的引用时,实际默认调用的是这个对象的toString()方法。
2、当打印的对象所在的类没有重写Object中的toString()方法时,那么调用的就是Object中定义的toString()方法。
返回次对象所在的类及对应在堆空间对象实体的首地址值
3、常常这样重写,将对象的属性值返回。
4、像Date类 String类 包装类 File类 等,已经 重写了toString()方法
4.7包装类(Wrapper)
针对八种基本定义相应的引用类型——包装类(封装类)
//JDK5.0以后,自动装箱和拆箱
Integer i3=12;//自动装箱 Integer i3=new Integer(12);
Boolean bb=false; //Boolean bb=new Boolean("true");
int i5=i3;//自动拆箱 int i5=i3.intValue();