Java中的Object类
在java中,Object类是所有类的父类,Java中所有的类都显示或者隐式的继承自Object类,也可以称Object为 老祖宗类.
toString() 把对象以字符串的形式返回
//在打印一个对象引用时,会打印对象的地址值,其实是在打印这个对象调用了toString方法的结果
Object类中的: 打印对象的地址值
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
目的: 打印对象时候,需要打印的是对象所有成员属性的值
解决: 重写toString()方法,对方法体进行重新定义
==比较对象的地址
equals() 可以使用equals方法比较内容,如果使用的是Object类型中的equals方法比较的还是对象的地址
目的:想要实现比较对象的内容
解决: 重写equals方法,自定义比较规则
public boolean equals(Object obj) {
return (this == obj);
}
public class ObjectDemo01 extends Object{
private String name;
private int age;
//空构造
public ObjectDemo01() {
// TODO Auto-generated constructor stub
}
//带参构造r
public ObjectDemo01(String name, int age) {
super();
this.name = name;
this.age = age;
}
//公共的设置器与访问器
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;
}
//只比较年龄 如果年龄相同就是一个对象
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
//判断obj 是否为ObjectDemo01类型的对象,如果是返回true,如果不是返回false
//instanceof 运算符只能用作对象的判断。
if(obj instanceof ObjectDemo01){
ObjectDemo01 o=(ObjectDemo01)obj;
return this.age == o.age;
}
return false;
}
public static void main(String[] args) {
ObjectDemo01 ob1=new ObjectDemo01();
ObjectDemo01 ob2=new ObjectDemo01();
System.out.println(ob1==ob2); //比较2个对象的地址
System.out.println(ob1.equals("")); //比较2个对象的内容
System.out.println(ob1.toString());
System.out.println("哈哈".equals("哈哈"));
ObjectDemo01 ob3=ob1;
System.out.println(ob3 == ob1);
}
@Override
//因为Java中所有的类都显示或者隐式的继承自Object类,通过继承的特性我们可以重写Object类中的toString()方法,自己重写一个方法,以下代码就是重写了Object类中的toString()方法.
public String toString() {
return name+","+age;
}
}
Java中的多态
*多态:一种事物的多种表现形式|形态
*多态的最终体现:父类引用执行子类对象
通过 父类引用执行子类对象 这句话可以知道,多态的的前提是必须类与类之间必须要有继承关系,这是多态的重要前提
多态的前提:
1.类与类之间要有继承关系
2.接口的实现
注意事项:
-
父类的引用会调用子类中重写的方法,没有重写就会去找父类的
-
父类无法使用子类中独有的内容,如果想要使用,需要转型
多态使用成员的特点:
- 多态使用成员变量:
- 编译运行看父类|左边|类型
- 多态使用成员方法:
- 编译看类型|左边|父类
- 运行找对象|右边|子类
public class Demo01 {
public static void main(String[] args) {
//多态
Person p=new Student();
Student s=new Student();
p.speak();
System.out.println(p.name);
}
}
class Person{
String name="张三丰";
void speak(){
System.out.println("说话");
}
}
class Student extends Person{
String name="张三";
void speak(){
System.out.println("文明用语...");
void study(){
System.out.println("good good study day day up");
}
}
/*
上面的代码中,Person p = new Student(); 便是多态,因为Student类继承了Person类,多态的前提是要有继承关系,当调用p.speak()时,由于子类Student中重写了speak()方法,所以,父类引用调用的是子类中重写的方法,输出结果是: 文明用语... ,如果子类中没有重写speak()方法,那么就会调用父类中的speak()方法.
*/
转型
上面说到,父类无法使用子类中独有的内容,如果想要使用,需要转型,那么如何转型呢?
转型有两种分别是:
-
向上转型–>自动类型提升:多态
-
向下转型–>强制类型转换:
格式: 子类类型 引用 = (子类类型)父类类型;
public class CastDemo02 {
public static void main(String[] args) {
//向上转型
KongziDie d=new KongziDie();
KongziDie k=new Kongzi();
k.teach();//多态:父类引用执行子类对象,调用子类中重写的方法; 输出王者
/*
向下转型容易遇到的异常: ClassCastException 类型转换异常
推荐使用运算符 instanceof
引用 instaceof 类型 判断前面的引用是否为后面类型的对象|是后面类型子类的对象,如果是返回ture,不是返回false
*/
//父类无法使用子类中独有的内容,所以需要转型,
//向下转型
if(k instanceof Brother){
Brother kk=(Brother)k;
kk.play();
}else{
Kongzi kk=(Kongzi)k;
kk.play();
}
}
}
class KongziDie{
void teach(){
System.out.println("做生意");
}
}
class Kongzi extends KongziDie{
void teach(){
System.out.println("论语");
}
void play(){
System.out.println("王者");
}
}
class Brother extends KongziDie{
void play(){
System.out.println("绝地求生");
}
}
多态的含义和作用
多态:是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。编程其实就是一个将具体世界进行抽象化的过程,多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话。
作用:可以提高代码的灵活性和扩展性,可以提高可扩充性和可维护性。
向上转型和向下转型
向上转型:父类的引用指向子类的对象
向下转型:把父类引用执行的子类对象强制转为子类类型
注意:无论是基本类型还是引用类型,小转大都是自动的,大转小都是强制的.
Java中的抽象类
* 被abstract修饰的类就是抽象类,抽象方法必须存在于抽象类中.
* 抽象方法: 没有方法体的方法
* 必须在与抽象类中
* 被abstract修饰的方法
*
* 注意:
* 1.抽象类可以存在抽象方法,也可以存在普通方法
* 2.抽象类不能实例化
* 3.抽象方法必须被重写
* 4.抽象类的使用:
* 1)具体子类:重写所有的抽象方法+按需新增
* 2)抽象子类:按需重写+按需新增
* 5.抽象方法一旦被重写可以不在被重写
* 6.abstract与static,private,final,native不能一起使用
public abstract class Develop {
abstract void work();//抽象方法
abstract void sleep();//抽象方法
void test(){//普通方法
System.out.println("哈哈哈,马上可以吃饭了...");
}
}
//因为抽象类不能被实例化,所以可以创建一个类来继承抽象类,这样便可以创建子类对象,调用子类中的方法.使用抽象类必须重写抽象类中的所有抽象方法.
//具体子类
public class Java extends Develop{
@Override
void work() {//重写抽象方法
System.out.println("边敲代码边睡觉");
}
void haha(){//重写抽象方法
System.out.println("聊天止于微笑");
}
@Override
void sleep() {
// TODO Auto-generated method stub
}
}
//抽象子类
abstract class Web extends Develop{
@Override
void work() {
System.out.println("网页开发");
}
//abstract void sleep();
void hehe(){
System.out.println("聊天止于呵呵");
}
}
//具体子类:
class Son extends Web{
@Override
void sleep() {
System.out.println("上课睡觉可真香!!!");
}
}
public class Test {
public static void main(String[] args) {
//创建子类对象,
Java java=new Java();
//调用重写后的抽象方法
java.haha();//输出 聊天止于微笑
//调用重写后的抽象方法
java.work();//输出 边敲代码边睡觉
Develop w=new Son();//多态,父类引用执行子类对象
w.sleep();//输出 上课睡觉可真香!!!
}
}
Java中的接口
接口 可以理解为特殊的抽象类
接口的优点
- 接口可以多实现,类只能单继承
- 可以提高代码的复用性
- 达到解耦的目的
- 定义开发规范
如果想要定义接口需要使用**interface**关键字
* jdk1.7版本及之前的:
* 属性: 公共的静态的常量 public static final 数据类型 变量名 = 赋值;
* 修饰符可以省略,默认是 public static final,可以按需省略
* 方法:
* 公共的抽象的方法 public abstract 返回值类型 方法名();
* 修饰符可以省略,默认public abstract
* 接口的jdk1.8的新特性:
* 1.default修饰的默认方法可以定义方法体
* 根据实现类使用
* 2.静态方法可以定义方法体
* 根据接口名字使用
注意:
* 1.抽象方法的使用必须重写
* 2.接口不能实例化
* 3.需要实现类来实现接口,使用接口中的内容
* 具体的实现类: 必须重写所有的抽象方法+按需新增
* 抽象的实现类: 按需重写 + 按需新增
* 抽象实现类的使用,需要子类继承抽象类,重写所有的抽象方法
* 4.类的继承使用extends关键字,实现使用implements关键字
* 5.类可以实现多个接口class Test implements Demo,A,B
* 6.一个类应该先继承后实现
* 7.只能类实现接口,继承父类,但是接口和接口之间只能多继承
* 8.类和类之间之能单继承
接口也是一种引用数据类型,可以等同看做类
- 如何定义接口,语法
[修饰符] interface 接口名{}
public interface A{}
2.接口中只能出现 : 常量 ,抽象方法
public interface A{
//常量(必须用public static final修饰)
public static final String SUCCESS = "success";
public static final double PI = 3.14;
// public static final是可以省略的
byte MAX_VALUE = 127;//(仍然是常量)
//抽象方法(接口中所有的抽象方法都是public abstract)
public abstract void m1();
//public abstract 是可以省略的.
void m2();
//接口方法不能带有主体
}
3.接口其实是一个特殊的抽象类,特殊在接口是完全抽象的
4.接口中没有构造方法,无法被实例化.
5.接口和接口之间可以多继承
interface B{
void m1();
}
interface C{
void m2();
}
interface D{
void m3();
}
interface E extends B,C,D{
void m1();
}
6.一个类可以实现多个接口.(这里的"实现"可以等同看做"继承")
public interface A{
//常量(必须用public static final修饰)
public static final String SUCCESS = "success";
public static final double PI = 3.14;
// public static final是可以省略的
byte MAX_VALUE = 127;//(仍然是常量)
//抽象方法(接口中所有的抽象方法都是public abstract)
public abstract void m1();
//public abstract 是可以省略的.
void m2();
//接口方法不能带有主体
}
interface B{
void m1();
}
interface C{
void m2();
}
interface D{
void m3();
}
interface E extends B,C,D{
void m4();
}
//implements是实现的意思,是一个关键字.
//implements和extends意义相同.
class MyClass implements B,C{
public void m1(){}
public void m2(){}
}
7.一个非抽象类实现接口,需要将接口中所有的方法"实现/重写/覆盖"
interface B{
void m1();
}
interface C{
void m2();
}
interface D{
void m3();
}
interface E extends B,C,D{
void m4();
}
//implements是实现的意思,是一个关键字.
//implements和extends意义相同.
class MyClass implements B,C{
//一个非抽象类实现接口,需要将接口中所有的方法"实现/重写/覆盖"
public void m1(){}//重写B接口中的方法
public void m2(){}//重写C接口中的方法
}