声明:由于学习所用环境是JDK1.8,所有java代码均在JDK1.8环境中调试通过,如果环境发生改变,可能会有错误发生!
一、Object类的toString()与equals(Object obj)方法
1、Object类
(1)Object类是所有类的基类;
(2)如果在类的声明中未使用extends关键字指明基类,则默认为Object类。
2、toString方法
(1)Object类中定义有public String toString()方法,其返回值是String类型,描述当前对象的有关信息。
(2)如果直接打印某对象的引用,则默认会调用这个对象的toString()方法,默认打印的内容中包含这个引用所指向的内存地址。
(3)可以根据需要在用户自定义类中重写toString()方法。
//调用默认toString()方法
public static void main(String[] args) {
Student stu=new Student("李丽",20,90.5);
System.out.println(stu);
}
//重写toString()方法
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score
+ "]";
}
3、equal方法
(1)Object类中定义有public boolean equals(Object obj) 方法,提供定义对象是否“相等”的逻辑。
(2)Object的equals方法定义为:x.equals(y),当x和y指向同一个地址时返回true,否则返回false。
public static void main(String[] args) {
Student stu1=new Student("张伟",20,83.5);
Student stu2=new Student("张伟",20,83.5);
System.out.println("stu1与stu2相等吗?"+stu1.equals(stu2));
}
说明:Object类的equals方法比较的是地址,代码中实例化了两次对象,在内存中申请了两块地址,所以结果false。
(3)String类中已经重写了equals(Object obj)方法,重写后的方法比较的是两个字符串的”内容”是否一样
(注意:==比较对象的引用)。
(4)可以根据需要在用户自定义类型中重写equals方法。
二、多态性
1、多态性的体现
(1)从方法的角度来看:方法的重载与重写
重载(overloading):根据传入的参数不同,完成的功能也不同
重写(override):子类根据需求重写父类中的方法。
(2)从对象的角度来看:对象的多态性主要分为两种:
向上转型: 子类对象->父类对象 (程序会自动完成)
格式:父类 父类对象=子类实例
向上转型后,因为操作的是父类对象,所以无法找到在子类中定义的新方法;但如果子类重写了父类的某个方法,则调用的是重写后的方法。
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public void say(){
System.out.println("父类say方法");
}
public void walk(){
System.out.println("父类的walk方法");
}
}
public class Student extends Person{
private double score;
public Student(){
}
public Student(String name,int age,double score){
super(name,age);
this.score=score;
}
public void learn(){
System.out.println("学生的任务是学习");
}
@Override
public void walk(){
System.out.println("学生的walk方法");
}
}
public class Testupper {
public static void main(String[] args) {
Student stu=new Student();
Person per=stu;
per.say();
per.walk();
per.learn(); //操作的是父类对象,调用子类方法报错
}
}
向下转型:父类对象->子类对象 (必须明确的指明要转型的子类类型)
格式:子类 子类对象=(子类)父类实例
注意:向下转型前先要向上转型。
public class Testdowm {
public static void main(String[] args) {
Person per=new Student(); //向上转型(确认student和person之间的关系)
Student stu=(Student)per; //向下转型
stu.walk();
stu.say(); //因为子类可以继承父类,所以stu调用父类函数
}
}
2、instanceof关键字
在java中可以使用instanceof关键字判断一个对象是否属于一个类的实例
格式:对象 instanceof 类 返回boolean类型
public static void method(Person per){
if(per==null){
System.out.println("不能传空值");
}else if(per instanceof Student){
Student stu=(Student)per; //向下转型
stu.learn();
}else if(per instanceof Worker){
Worker worker=(Worker)per; //向下转型
worker.work();
}
}
3、final关键字
在JAVA中声明类、属性和方法时,可以使用关键字final来修饰。
注意:
1.final修饰变量(成员变量或局部变量),则成为常量,只能赋值一次
final 类型 variableName;
修饰成员变量时,定义时同时给出初始值,而修饰局部变量时不做要求。
2.final修饰方法,则该方法不能被子类重写
final 返回值类型 methodName(paramList)
{
…
}
3. final修饰类,则类不能被继承
final class finalClassName{
…
}
三、抽象类与接口
1、抽象类
用abstract修饰的类即为抽象类
abstract class 抽象类名{
}
抽象类不能被实例化,必须被继承,抽象方法必须被重写,生成它的子类
由abstract修饰的方法就是抽象方法,抽象方法没有方法体。
抽象类不一定要包含抽象方法,若类中包含了抽象方法,则该类必须被定义为抽象类
如果一个子类没有实现抽象父类中所有的抽象方法,则子类也成为一个抽象类。
构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法。
public abstract class Vehicle {
public abstract void run();
}
public class Moto extends Vehicle{
@Override
public void run() {
System.out.println("骑摩托车去上班");
}
}
public class Car extends Vehicle{
@Override
public void run() {
System.out.println("开车去上班");
}
}
public class Person {
public void goWork(Vehicle v){
v.run();
}
}
public class Test {
public static void main(String[] args) {
Person person =new Person();
Moto m=new Moto();
Car c=new Car();
person.goWork(m);
person.goWork(c);
}
}
2、接口
接口(interface)是抽象方法和常量值的定义的集合。
接口是一种“标准”、“契约”。
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只能包含常量和方法的定义,而没有变量和方法的实现。
(1)接口的声明语法
包括接口声明和接口体
完整的接口声明:
[public] interface 接口名称[extends listOfSuperInterface] { … }
接口体包括常量定义和方法定义
常量定义: type NAME=value; 该常量被实现该接口的多个类共享; 具有public ,final, static的属性.
方法体定义:具有 public和abstract属性
public interface Fly {
public static final int SPEED=200; // 常量
public abstract void fly();
}
public class Kite implements Fly{
@Override
public void fly() {
System.out.println("风筝飞翔...");
}
}
(2)接口的实现类
与抽象类一样,接口要使用也必须通过子类,子类通过 implements关键字实现接口
一个类可以实现多个接口,在 implements子句中用逗号分开
非抽象子类必须实现接口中定义的所有方法
实现格式:
class 子类 implements接口A,接口B…{
}
(3)接口的使用规则
接口中所有的方法都是public abstract。
在接口中声明方法时,不能使用static,final,synchronized,private,protected等修饰符。
一个接口可以继承自另一个接口。
java中不允许类的多继承,但允许接口的多继承。
接口中可以有数据成员,这些成员默认都是public static final
一个类可以一个类,继承多个接口 eg:public class Dog extends Animal implements Eating{...}
(4)接口的用途
(1)通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系.
(2)通过接口指明多个类需要实现的方法
(3)通过接口了解对象的交互界面,而无需了解对象所对应的类