该篇博客目录
1、Object类概述(toString,equals)
2、JAVA的多态
3、JAVA抽象类(abstract)
4、JAVA的接口(interface)
一、Object类概述(toString,equals)
- Object类是所有类的父类
- 如果一个类没有使用extends明确标识继承另外一个类,那么该类默认继承Object类
- Object类的方法适用于所有子类
Object类常用方法(toString,equals)
1、toString方法
- 返回该对象的哈希code码(对象地址字符串)
- 下面是toString的Demo
父类
package com.xxxx;
public class Animal {
public int age=10;
public Animal() {
System.out.println("Animal类执行了");
age=20;
}
}
子类
package com.xxxx;
public class Dog extends Animal {
public Dog() {
System.out.println("dog执行");
}
public String toString() {
return "Dog[age="+age+"]";
}
}
测试类
package com.xxxx;
public class Initail {
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog =new Dog();
System.out.println(dog);
}
}
//输出:
//Animal类执行了
//dog执行
//Dog[age=20]
//没有toString输出:
//Animal类执行了
//dog执行
//com.xxxx.Dog@57fa26b7
2、equals方法
比较的是对象的引用是否指向同一块内存地址
不是比较对象的成员变量的值,如果想比较值,可以重写equals方法
“==”与equals的区别
a、“==”
- 基本类型:比较的是两个数据的值是否相等
- 引用类型:比较的是两个对象是否指向同一块内存地址,就比较对象是否相等
b、equals
- 引用类型:比较的是两个对象是否指向同一块内存地址,就比较对象是否相等
- 不过equals可以重写,使得比较对象的成员变量的值是否相等
下面是关于equals重写的Demo
父类
package Obj;
public class Obj_Father {
final private int a=10;
public Obj_Father()
{
}
}
子类(重写了equals)
package Obj;
public class Obj_Child extends Obj_Father{
public int d;
public Obj_Child() {
super();
}
//重写equals方法,使得equals比较两个对象的值,而不是比较两个对象
@Override
public boolean equals(Object obj) {
if (this == obj)//先判断两个引用是否相等
return true;
if (obj == null)//若是空则无需比较
return false;
if (getClass() != obj.getClass())//通过两个对象的类型是否相同
return false;
Obj_Child other = (Obj_Child) obj;//因为上面已经比较了两个对象类型是否相同,所以这句转换语句也是
理所当然
if (d != other.d)//判断两个对象的属性值是否相同
return false;
return true;
}
}
测试类
package Obj;
public class Obj_main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Obj_Child obj1=new Obj_Child();
obj1.d=10;
Obj_Child obj2=new Obj_Child();
obj2.d=10;
if(obj1.equals(obj2))
{
System.out.println("两对象值相同");
}
else if(obj1==obj2)
{
System.out.println("两对象相同");
}
}
}
//输出
//两对象值相同
如果没有重写equals,则都不会输出,因为都比较了两对象是否指向同一块内存地址
二、JAVA的多态
指对象在不同时刻(比如:父子类中)表现出来的不同状态
1、使用多态的前提
- 要有继承关系
- 要有方法重写
- 经常会有父类引用指向子类对象如:父类 对象名=new 子类();
2、引用多态
- 父类引用可以指向本类对象:父类 对象名=new 父类();
- 父类引用可以指向子类对象:父类 对象名=new 子类();
测试类Demo
package Obj;
public class Obj_main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Obj_Father obj1=new Obj_Father();//父类引用指向本类对象
Obj_Father obj2=new Obj_Child();//父类引用指向子类对象
}
}
3、方法多态
- 创建本类对象时,调用的方法是本类方法
- 创建子类对象时,调用的方法为子类重写的方法,(若没有重写,则调用继承的方法)
- 下面是方法多态的Demo
父类
package Obj;
public class Obj_Father{
public void print() {
System.out.println("父类中的print方法");
}
}
子类
package Obj;
public class Obj_Child extends Obj_Father{
public void print(){
System.out.println("子类中的print方法");
}
}
测试类
package Obj;
public class Obj_main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Obj_Father obj1=new Obj_Father();//父类引用指向本类对象
Obj_Father obj2=new Obj_Child();//父类引用指向子类对象
obj1.print();//调用父类print方法
obj2.print();//调用子类print方法
//虽然obj1和obj2都是父类引用,但是指向的对象不同
}
}
//输出
//父类中的print方法
//子类中的print方法
4、多态中引用类型转换(instanceof)
- 向上类型转换(隐式/自动类型转换),小类型到大类型的转换(无风险)
- 向下类型转换(强制类型转换),大类型到小类型的转换(有风险)
instanceof
格式:父类引用 instanceof 子类名
- instanceof判断一个引用是否是某个类型或是某个类型的子类型(返回bool值)
- instanceof运算符,解决引用对象的类型,避免类型转换的安全性问题
引用类型转换的Demo
父类
package Obj;
public class Obj_Father{
public void print() {
System.out.println("父类中的print方法");
}
}
子类1
package Obj;
public class Obj_Child extends Obj_Father{
public void print(){
System.out.println("子类中的print方法");
}
}
子类2
package Obj;
public class Obj_Child_second extends Obj_Father {
}
测试类
package Obj;
public class Obj_main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Obj_Child obj1=new Obj_Child();
//利用父类的引用来指向子类对象(自动类型提升/向上类型转换)
Obj_Father obj2=obj1;
//将父类引用转换成子类引用,存在风险,报错
//Obj_Child obj3=obj2;
if(obj2 instanceof Obj_Child)
{
//将父类引用转换成子类引用(利用强制转换/向下类型转换)
Obj_Child obj3=(Obj_Child)obj2;
}else {
System.out.println("obj2和obj3无法进行类型转换 转换成Obj_Child类型");
}
//将父类引用转换成Obj_Child_second子类的引用,运行时错误,因为obj2指向的是Obi_Child的对象,无法转
换成Obj_Child_second的对象
if(obj2 instanceof Obj_Child_second)//如果obj2对象里面含有Obj_Child_second类型的元素就返回true
{
Obj_Child_second obj4=(Obj_Child_second)obj2;
//1.编译时 Obj_Child_second 2.运行时 Obj_Child类型 两个类型不匹配,所以运行是出错
}else {
System.out.println("obj2和obj4无法进行类型转换 转换成Obj_Child_second类型");
}
}
}
//输出:obj2和obj4无法进行类型转换 转换成Obj_Child_second类型
三、JAVA抽象类(abstract)
1、定义
类前使用abstract关键字修饰,即为抽象类
2、抽象类应用场景
- 某个父类只知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法(抽象类是约束子类必须有哪些方法)
- 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为模板,从而避免子类设计的随意性
3、抽象类的作用/目的
限制规定子类必须实现某些方法,但不关注实现细节
4、使用规则
- abstract定义抽象类
- abstract定义抽象方法(只声明,不实现)
- 包含抽象方法的类一定是抽象类
- 抽象类中可以包含普通的方法,也可以没有抽象方法
- 抽象类不能直接创建,可以定义引用变量指向子类对象
- 使用了abstract将会与private、final冲突
5、下面是抽象类的Demo
抽象类
package abstract_test;
//抽象类
public abstract class Tel {
//抽象方法
public abstract void call();
}
抽象类的子类1
package abstract_test;
public class Phone extends Tel {
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("打电话");
}
}
抽象类的子类2
package abstract_test;
public class Newphone extends Tel {
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("新手机的打电话");
}
}
测试类
package abstract_test;
public class main_abs {
public static void main(String[] args)
{
Tel t1=new Phone();
t1.call();
Tel t2=new Newphone();
t2.call();
}
}
//输出
//打电话
//新手机的打电话
6、下面是抽象类的另一个Demo
需求:现有Shape圆形类,用Rectangle矩形和Circle圆形子类,求图形的周长和面积
Shape类
package project1;
public abstract class Shape {
//求周长
public abstract double Pre(double a,double b);
public abstract double Pre(double r);
//求面积
public abstract double Acr(double a,double b);
public abstract double Acr(double r);
}
Rectangle类
package project1;
public class Rectangle extends Shape {
@Override
public double Pre(double a,double b) {
// TODO Auto-generated method stub
double c=2*a+2*b;
return c;
}
@Override
public double Acr(double a,double b) {
// TODO Auto-generated method stub
double c=a*b;
return c;
}
}
Circle类
package project1;
public class Circle extends Shape {
final double PI=3.14;
@Override
public double Pre(double r) {
// TODO Auto-generated method stub
double p=2*PI*r;
return p;
}
@Override
public double Acr(double r) {
// TODO Auto-generated method stub
double p=PI*r*r;
return p;
}
}
测试类
package project1;
public class main_Shape {
public static void main(String[] args) {
// TODO Auto-generated method stub
Shape rec=new Rectangle();
Shape cir=new Circle();
double a=1.1;
double b=2.2;
double r=3.3;
double c=rec.Pre(a,b);
double d=rec.Acr(a,b);
double e=cir.Pre(r);
double f=cir.Acr(r);
System.out.println("矩形的周长:"+c);
System.out.println("矩形的面积:"+d);
System.out.println("圆形的周长:"+e);
System.out.println("圆形的面积:"+f);
}
}
四、JAVA的接口(interface)
1、接口概念
- 接口可以理解为一种特殊的类(由常量和公共的抽象方法组成)
- 接口其实是一个规范,用来约束类,必须实现某些方法
2、接口与抽象类的区别
- 某个子类可以继承多个接口,但是只能继承一个类(也包括抽象类)
- 接口中都是抽象方法,抽象类中可以有抽象方法也可以有普通方法
3、接口定义(使用interface)
格式:
[修饰符] interface 接口名[extends 父接口1,父接口2....]
{
零个到多个常量定义;
零个到多个抽象方法声明;
}
- Tip1:接口就是用来被继承的,被实现的,修饰符用public
- Tip2:接口可以多继承,继承多个父接口。但类是单继承,只能继承一个父类
4、接口中的常量与方法
- 常量:接口中的属性都是常量,即使定义时不添加public static final修饰符,系统也会自动添加
- 方法:接口中的方法都是抽象方法,即使定义时不添加public abstract,系统也会自动添加
5、使用接口(通过类来实现接口)(implements)
JAVA中一个类只能继承一个父类不够灵活,通过实现多个接口作为补充相当常见
格式
- 1
修饰符 class implements 接口1,接口2 - 2
修饰符 class 类名 extends 父类 implements 接口1,接口2…
{
…
}
6、下面是一个接口知识点的Demo
父类(该父类为抽象类)
package abstract_test;
public abstract class Tel {
public abstract void call();
}
接口
package abstract_test;
public interface PlayGame {
public void play();
}
Phone子类,不是接口的子接口
package abstract_test;
public class Phone extends Tel {
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("打电话");
}
}
Newphone子类,既是子类也是子接口
package abstract_test;
public class Newphone extends Tel implements PlayGame {
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("新手机的打电话");
}
//实现接口的方法
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("Newphone可以打游戏");
}
}
GamePhone子接口,不是子类
package abstract_test;
public class GamePhone implements PlayGame {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("GamePhone可以打游戏");
}
}
测试类
package abstract_test;
public class main_abs {
public static void main(String[] args)
{
Tel t1=new Phone();
t1.call();
Tel t2=new Newphone();
t2.call();
PlayGame t3=new GamePhone();
t3.play();
PlayGame t4=new Newphone();
t4.play();
}
}
//输出
//打电话
//新手机的打电话
//GamePhone可以打游戏
//Newphone可以打游戏
7、使用匿名内部类实现接口
直接看下面的Demo(只需在上面的Demo中的测试类中添加语句就好)
测试类(两种方法)
package abstract_test;
public class main_abs {
public static void main(String[] args)
{
Tel t1=new Phone();
t1.call();
Tel t2=new Newphone();
t2.call();
PlayGame t3=new GamePhone();
t3.play();
PlayGame t4=new Newphone();
t4.play();
////////使用匿名内部类实现接口////////
PlayGame t5=new PlayGame() {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("使用匿名内部类实现接口");
}
};//别忘记分号
t5.play();
//第二种方法
new PlayGame() {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("使用匿名内部类实现接口第二种方法");
}
}.play();
}
}
//输出:
//打电话
//新手机的打电话
//GamePhone可以打游戏
//Newphone可以打游戏
//使用匿名内部类实现接口
//使用匿名内部类实现接口第二种方法
16万+

被折叠的 条评论
为什么被折叠?



