JavaSE--面向对象

JavaSE – 面向对象

一、面向对象概述

1.1 面向对象和面向过程

面向过程:面向过程其实就是面向具体的每一个步骤和过程,也就是面对具体的每一个功能函数,这些功能函数相互调用,完成需求。即就是朝着要实现的功能,一步步的去操作。

面向过程:面向对象是基于面向过程,对象是将功能进行了封装。只要找到了具体的类,创建出对象,就可以调用其中的具体功能。面向对象也是用来解决问题的一种思维模式。即就是朝着要实现功能的目标,有该功能就调用类。没有的话,就自己设计类。

1.2 面向对象和面向过程差异(面向对象的好处)

  1. 面向对象是一种更符合人们思考习惯的思想
  2. 面向过程更多的体现的是执行者,面向对象更多的体现是指挥者。指挥对象做事情
  3. 面向对象复杂的问题简单化

1.3 面向对象程序设计

案例:把大象装进冰箱

针对具体的需求,可以使用名词提炼法进行分析,寻找具体的对象

  • 要求:把大象装冰箱里
  • 对象:大象、冰箱

实施的步骤

  1. 打开冰箱门。
  2. 将大象装进去。
  3. 关闭冰箱门。

以上步骤有个问题就是:这些行为的发起者是谁???谁来完成???

分析发现打开、装、关闭都是冰箱的功能。即冰箱对象具备如下功能

  • 冰箱打开。
  • 冰箱存储。
  • 冰箱关闭。

用伪代码描述,上述需求中有两个具体的事物 大象 和 冰箱 。

public class 大象{}// 大象类
public class 冰箱{// 冰箱类
    打开(){};
    存储(大象){};
   	关闭(){};
}

当把具体的事物描述清楚之后,需要使用这些具体的事物Java使用具体的事物,需要通过new关键字来创建这个事物的具体实例

// 创建冰箱对象
冰箱 bx = new 冰箱(); 
// 调用冰箱的功能
对象.功能();
bx.打开();
bx.存储(new 大象());
bx.关闭();

总结:

  1. 先按照名词提炼问题领域中的对象
  2. 对象进行描述,其实就是在明确对象中应该具备的属性功能
  3. 通过 new关键字 就可以创建该事物的具体对象
  4. 通过该对象调用它以后的功能。使用 . 访问属性和调用方法() 如: 大象.鼻子

二、类和对象

2.1 类与对象的概念

:现实生活中一种事物的抽象,把对事物的描述做成数据也就是属性,把事物具备的功能做成方法。

对象对象object)代表现实世界中可以明确标识的一个实体。例如:一名学生、一张桌子、一个圆、一个按钮甚至一笔贷款都可以当做是一个对象。每个对象都有自己独特标识状态行为

2.2 类与对象的区别

用于描述现实事物的它将现实事物进行抽象化,模板化描述。将事物的特点(属性)行为封装在其中。比如小汽车的图纸,图纸就是小汽车的模版。图纸上画着小汽车的各种特点和功能要求。

对象现实生活中存在的具体实例个体。即生活中看到每一个事物,以及我们想象中的事物抽象的概念,都是某一类事物的实例个体而这些个体都属于某一类事物,即这些个体都是某一类事物中的具体的实例。比如,小汽车就是一类事物,而小汽车又是基于小汽车图纸制造出来的真实个体。因此我们生活中的每一个实物都可以理解为是某一类事物的中的一个个体。创建对象通过对象就可以调用具体的属性行为

创建对象:new + 构造方法()

构造方法:无返回值,名字与类名相同,功能是配合new关键字来创建对象。

注意:构造方法无返回值因为不需要额外信息数据。与类名一致是因为创建同名对象。

构造方法根据属性的不同有多种重载形式,通常把无参数的构造方法称为无参构造

对象的内存:new + 构造方法() 创建的对象,在堆内存中开辟空间,属性有默认值

2.3 成员变量和局部变量的区别

  1. 内存中的位置不同:

    成员变量:成员变量存储在堆内存的对象中

    局部变量:局部变量存储在栈内存的方法中

  2. 定义的位置不同:

    成员变量:定义在类中

    局部变量:定义在方法中

  3. 生命周期不同:

    成员变量:成员变量随着对象的创建而创建,消失而消失

    局部变量:局部变量压栈出现,弹栈消失

2.4 匿名对象

​ 当我们的对象只是为了调用某个方法或者作为参数时,使用匿名对象,其实就是不给创建的对象以引用。

class Car
{
	String color;// 颜色
	int number;// 轮胎数
	//描述行为,即方法
	public void run()
	{
		System.out.println(color + ":" + number);
	}
}

class CarDemo
{
    public static void main(String[] args)
	{
         //创建Car.class类的对象。
		 Car c = new Car();
         //调用run方法
         c.run();
         //创建Car.class类的对象。
         Car c2 = new Car();
        //调用run方法
         c2.run();
     }
}

匿名对象的使用场景:当对象对方法进行调用时,而且只调用一次时,可以简化成匿名对象来书写

Car c = new Car();// 创建对象Car
c.run();// 调用run()方法

// 使用匿名对象并调用run()方法
new Car().run();

匿名对象也可以作为参数传递

class CarDemo
{
    public static void main(String[] args)
	{    
        Car c = new Car();// 创建Car对象
        show(c);    //简化成 show(new Car());//把匿名对象作为实际参数进行传递。
    }
    public static void show(Car cc)  // Car cc = c;  Car cc = new Car();
	{
		cc.color = "red";
		cc.number = 4;
		cc.run();
	}
}

三、封装

封装:是指隐藏对象的属性和实现的细节,仅对外提供公共访问方式。在类定义中用private关键字来实现封装。

封装的特点:

  1. 隐藏了实现细节
  2. 提高了代码的复用性
  3. 提高安全性

private关键字:访问修饰符,代表私有的属性和方法,只能自己访问,对外访问不到

对外访问:private修饰的属性访问不到,就需要提供getXxx()方法和setXxx()方法,即就是对外设置或者获取属性的方法.

构造方法:没有返回值,方法名和类名一致,用来完成初始化,不需要返回值

​ 构造方法不需要私有化,否则无法进行对象的创建.

例如:

public class Demo{
  private String name;// 姓名
  // 空构造
  public Demo(){
    
  }
  // 全构造
  public Demo(String name){
    this.name = name;
  }
}

构造方法和一般方法的区别:

  1. 构造方法只执行一次,一般方法可以多次执行
  2. 构造方法在初始化时使用,一般方法针对自己需求使用(当需要时进行调用即可使用)

this关键字:代表当前对象,当抽象属性和参数同名时,用this代表当前对象

this调用当前属性this.属性;

this调用当前方法this.方法(参数列表);

this调用构造方法this(参数列表);

构造函数之间的调用可以通过this关键字来完成。

// Person类
class Person 
{
	// Person的成员属性
	private int age;
	private String name;
	// 无参数的构造函数
	public Person()
	{
	}
	//给姓名初始化的构造函数
	public Person(String name)
	{
		this.name = name;
	}
	//给姓名和年龄初始化的构造函数
	public Person(String nm , int a)
	{
		//由于已经存在给姓名进行初始化的构造函数 name = nm;因此只需要调用即可
		//调用其他构造函数,需要通过this关键字来调用
		this(nm);
		//给年龄初始化
		age = a;
	}
}

构造函数之间的相互调用可以通过this关键字完成

构造函数调用格式:

this(参数列表);

方法的自调用

this.XXX(参数列表)

super关键字:父类类的引用

四、static

static 静态的,代表的是类级别的属性和方法,是把非私有的属性进行共享使用

static修饰的方法: 直接使用类名.方法()调用,不需要对象,但是不能调用非静态方法,因为非静态方法的对象还没创建出来.

static修饰的属性: 是类级别的全对象共享,只要有一个对象对其进行操作其他对象单位该静态属性也会随之发生变化

静态方法使用注意事项:

  1. 静态方法不能访问非静态的成员。但是非静态可以访问静态成员的。

    说明静态的弊端在于访问出现局限性。好处是可以直接被类名调用

  2. 静态方法中不允许出现this,super关键字。

    静态不仅可以修饰方法,同时静态也可以修饰成员变量

// Circle类
class Circle
{
	// 圆的半径
	private double radius = 10;
	// 圆周率,由于圆周率是固定值,因此所有对象共享这个数据
	// 没有必要每个对象中拥有这个数据,因此可以使用静态修饰
	public static double pi = 3.14;
	// 带参数的构造函数
	public Circle(double radius)
	{
		this.radius = radius;
	}
	// 获取圆面积
	public double getArea()
	{
		return radius * radius * pi;
	}
}
// 测试类
class CircleDemo 
{
	public static void main(String[] args) 
	{
        // 匿名对象调用getArea方法
		System.out.println(new Circle(3).getArea());
	}
}

如果pi这个变量没有被静态修饰的话,当创建Circle对象时每个对象中都会有pi这个变量,但是pi是个固定不变的值,没有必要每个对象中拥有,这时可以将这个变量静态修饰,让所有对象共享**就可以了。

静态变量和成员变量的区别

  1. 变量所属不同

    静态变量所属于,也称为类变量

    成员变量所属于对象,也称为实例变量(对象变量)

  2. 内存中的位置

    静态变量存储于方法区中的静态区中。

    成员变量存储于堆内存中。

  3. 在内存中出现的时间

    静态变量随着类的加载而加载,随着类的消失而消失

    成员变量随着对象的创建而在堆内存中出现,随着对象的消失而消失

五、继承

继承:使用关键字extends,让一个类能够访问到一个类的非private属性和方法,提高被继承类的代码复用性。

同名属性:优先使用自己定义的,在自己的方法中通常有缺省的this来明确调用的是谁的属性,可以使用super关键字来代表父类进一步访问到父类的属性。

同名方法:发生了方法的重写

继承的好处:

  1. 提高了代码的复用性,提高软件开发效率
  2. 让类与类之间有了关系,提供多态的前提

Java中只支持单继承,不支持多继承

但是Java支持多层继承(继承体系)

// 类 -- A
class A{}
// 类 B 继承 A
class B extends A{}
// 类 C 继承 B
class C extends B{}

final关键字:意为最终,不可变的。可以修饰类,类的成员,以及局部变量

final修饰类: 不可继承

final修饰方法: 不可重写

final修饰变量: 称为常量,有初始值不可以被修改

final修饰的引用变量: 引用不能改,引用的对象的值可以修改

继承-子父类中成员方法特点-重写

​ 当在程序中通过对象调用方法时,会先在子类中查找有没有对应的方法,弱子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法.

就近原则

// 父类
class Fu{
  // 方法 -- show()
	public void show(){
		System.out.println("Fu类中的show方法执行");
	}
}
// 子类 继承 父类
class Zi extends Fu{
  // 方法 -- show2()
	public void show2(){
		System.out.println("Zi类中的show2方法执行");
	}
}
// 测试类
public  class Test{
	public static void main(String[] args) {
        // 创建子类对象
		Zi z = new Zi();
		z.show(); //子类中没有show方法,但是可以找到父类方法去执行
		z.show2();// 调用子类的show2方法
	}
}

成员方法特殊情况——覆盖

子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为override重写复写或者覆盖

// 父类
class Fu
{
  	// 方法 -- show()
	public void show()
	{
		System.out.println("Fu show");
	}
}
// 子类 继承 父类
class Zi extends Fu
{
	//子类复写了父类的show方法
	public void show()
	{
		System.out.println("Zi show");
	}
}

子父类中构造函数特点(super())

​ 在创建子类对象时,父类的构造函数先执行,因为子类中所有构造函数第一行有默认的隐式super()语句,调用本类中的构造函数用this(实参列表)语句,调用父类中的构造函数用super(实参列表)。

为什么子类对象初始化都要访问父类中的构造函数?因为子类继承了父类的内容,所以创建对象时必须要先看父类是如何对内容进行初始化的

public class Test {
	public static void main(String[] args) {
		new Zi();
	}
}
// 父类
class Fu{
	int num ;
	public Fu(){
		System.out.println("Fu构造函数"+num);
		num = 4;
	}
}
// 子类 继承 父类
class Zi extends Fu{
	public Zi(){
		System.out.println("Zi构造函数"+num);
	}
}
// 执行结果:
// Fu构造函数0
// Zi构造函数4 

子类中的构造函数为什么有一句隐式的super()呢?

原因子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作才可以更方便的使用父类中的内容。

当父类中没有空参数构造函数时,子类的构造函数必须有显示的super()语句指定要访问的父类中的构造函数

class Fu extends Object
{
	// 无参构造
	public Fu()
	{
		//super();
		//显示初始化。
		System.out.println("fu constructor run..A..");
	}
	// 有参构造
	public Fu(int x)
	{
		//显示初始化。
		System.out.println("fu constructor run..B.."+x);
	}
}
class Zi extends Fu
{
	// 无参构造
	public Zi()
	{
		//super();
		System.out.println("zi constructor run..C..");
	}
	// 有参构造
	public Zi(int x)
	{
		super();
		System.out.println("zi constructor run..D.."+x);
	}
}
// 测试类
class Demo
{
	public static void main(String[] args)
	{
        // 匿名对象 
		new Zi();
		new Zi(3);
	}
}

六、抽象类

​ 分析事物时,进行向上抽取,抽取他们的共同属性(最能体现继承的特性)。例如:

// 抽象类 -- quanKe
  abstract class quanKe 
{
	abstract void haoJiao();//抽象函数。需要abstract修饰,并分号;结束
}
// 类 -- Dog 继承 quanKe
class Dog extends quanKe
{
	// 对抽象类犬科中的方法进行重写
	public void haoJiao()
	{
		System.out.println("汪汪汪汪");
	}
}
// 类 -- Wolf 继承 quanKe
class Wolf extends 犬科
{
	// 对抽象类犬科中的方法进行重写
	public void haoJiao()
	{
		System.out.println("嗷嗷嗷嗷");
	}
}

关键字:abstract

abstract:意为抽象,可以修饰类和方法。修饰类的时候不能实例化,修饰方法的时候没有方法体{ }.

注意:

  1. absract和finnal :final修饰的类不可以被继承,abstract修饰的类必须被继承
  2. abstract和static: static修饰的方法可以直接通过类调用,abstract修饰的方法不能被调用
  3. abstract和private:private不能被继承,abstract必须被继承或者必须被重写

七、接口

接口:是一个极度的抽象类,里面全是抽象方法,接口中可以定义变量,但是变量必须有固定的修饰符修饰,也就是用定义常量的方法定义接口中的变量。

​ 关键字:interface

接口中成员的特点

​ 1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final所以接口中的变量也称之为常量

​ 2、接口中可以定义方法,方法也有固定的修饰符,public abstract。

​ 3、接口中的成员都是公共的

​ 4、接口不可以创建对象

​ 5、子类必须覆盖掉接口中所有的抽象方法后子类才可以实例化。否则子类是一个抽象类。

interface Demo// 定义一个名称为Demo的接口。
{
	public static final int NUM = 3;
  	// 抽象方法 
	public abstract void show1();
	public abstract void show2();
}
// 定义子类去覆盖接口中的方法。子类必须和接口产生关系,类与类的关系是继承,类与接口之间的关系是 实现。通过 关键字 implements
class DemoImpl implements Demo// 子类实现Demo接口。
{
	// 重写接口中的方法。
	public void show1(){}
	public void show2(){}
}

接口-多实现

接口最重要的体现: 解决多继承的弊端。将多继承这种机制在java中通过多实现完成了。

// 接口A
interface A
{
  	// 抽象方法 -- show1()
	public void abstract show1();
}
// 接口B
interface B
{
    // 抽象方法 -- show2()
	public void abstract show2();
}
// 类C 实现 接口A,B
class C implements A,B// 多实现。同时实现多个接口。
{
  	// 重写接口A,B中的抽象方法show1,show2
	public void show1(){}
	public void show2(){}
}

解决多继承的弊端

弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性。

其实核心原因就是在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。

而在多实现里因为接口中的功能都没有方法体,由子类来明确,来源确定就是实现他们的实现类。

子类继承类同时实现接口

子类通过继承父类扩展功能通过继承扩展的功能都是子类应该具备的基础功能。如果子类想要继续扩展其他类中的功能呢?这时通过实现接口来完成。

// 父类
class Fu
{
  	// 方法 -- show()
	public void show(){}
}
// 接口 -- Inter
interface Inter
{
  	// 抽象方法 -- show1()
	public abstract void show1();
}
// 子类 继承 父类 实现 接口Inter
class Zi extends Fu implements Inter
{
	// 重写接口中的抽象方法show1()
	public void show1(){}
}

接口的多继承

多个接口之间可以使用extends进行继承

// 接口A
interface A{
  	 // 抽象方法 -- show()
	 public abstract void show();
}
// 接口B
interface B{
  	// 抽象方法 -- show1()
	public abstract void show1();
}
// 接口C
interface C{
  	// 抽象方法 -- show2()
	public abstract void show2();
}
// 接口D 继承 接口A,B,C
interface D extends A,B,C{
  	 // 抽象方法 -- show3()
	 public abstract void show3();
}

在开发中如果多个接口中存在相同方法,这时若有个类实现了这些接口,那么就要实现所有接口中的方法,由于接口中的方法是抽象方法,子类实现后也不会发生调用的不确定性

没有抽象方法的抽象类的由来

在开发中,若一个接口中有多个抽象方法,但是实现这个接口只使用其中某些方法时,这时我们仍然需要将其他不使用的方法实现,这样明显不符合我们的要求,但不实现这些方法又不行。那么怎么办呢?可以使用一个抽象类作为过渡,而这个抽象类实现这个接口所有方法都以空实现存在。这就是没有抽象方法的抽象类的存在价值。我们只要继承这个抽象类,覆盖其中需要使用的方法即可。

//拥有多个方法的接口
interface Inter{
  	// 抽象方法
	public abstract void show();
	public abstract void show1();
	public abstract void show2();
	public abstract void show3();
}
//作为过度的抽象类,此类将接口的所有方法都实现,这里的实现是空实现
abstract class AbsInter implements Inter{
 	// 重写接口中的抽象方法
	public void show(){}
	public void show1(){}
	public void show2(){}
	public void show3(){}
}
/*
//此类直接实现Inter,但只使用其他show和show2方法,这样导致其他两个方法也要实现
//不符合我们的要求
class SubInter2 implements Inter{

	public void show() {
		System.out.println("show");
	}
	public void show1() {
	}
	public void show2() {
		System.out.println("show2");
		
	}
	public void show3() {
	}
}
*/
//此类只使用接口中的show和show2方法,只要覆盖抽象类中的show和show2即可
class SubInter extends AbsInter{
	public void show(){
		System.out.println("show");
	}
	public void show2(){
		System.out.println("show2")
    }
}
接口的好处:
1. 接口的出现扩展了功能
2. 接口其实就是暴露出来的规则
3. 接口的出现降低了耦合性,即设备与设备之间实现了解耦

接口与抽象类的区别:

相同点:

  • 都位于继承的顶端,用于被其他实现继承;
  • 不能实例化;
  • 都包含抽象方法,其子类都必须覆写这些抽象方法;

区别:

  • 抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性;接口只能包含抽象方法,极度的抽象类;
  • 一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;接口弥补了Java的单继承的不足

二者的选用:

  • 优先选用接口,尽量少用抽象类;
  • 需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;

八、多态

多态的体现: 父类的引用或者接口的引用指向了自己的子类对象

Dog d = new Dog();// Dog对象的类型是Dog类型。
Animal a = new Dog();// Dog对象的类型右边是Dog类型,左边Animal类型。

多态的好处:

提高了程序的扩展性。

多态的弊端:

​ 通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。

多态的前提:

  1. 必须有关系:继承,实现
  2. 通常都有重写操作

多态-转型

父类的引用 指向子类对象时,就发生了向上转型,即把子类类型对象转成了父类类型。向上转型的好处是隐藏子类类型,提高了代码的扩展性

但向上转型也有弊端,只能使用父类共性的内容,而无法使用子类特有功能,功能有限制。

// 描述动物这种事物的共性eat
abstract class Animal{
  	// 抽象方法 -- eat()
	public abstract void eat();
}
// 类Dog 继承 Animal
class Dog extends Animal{
  	// 重写Animal中的抽象方法eat()
	public void eat(){
		System.out.println("啃骨头");
	}
  	// Dog特有的方法lookHome()
	public void lookHome(){
		System.out.println("看家");
	}
}
// 类Cat 继承 Animal
class Cat extends Animal{
  	// 重写Animal中的抽象方法eat()
	public void eat(){
		System.out.println("吃鱼");
	}
  	// Cat特有的方法CatchMouse
	public void catchMouse(){
		System.out.println("抓老鼠");
	}
}
// 测试类
public class Test {
	public static void main(String[] args) {
		Animal a = new Dog(); //这里形成了多态
		a.eat();
		//a.lookHome();
      	//使用Dog特有的方法,需要向下转型
		Dog d = (Dog)a;
		d.lookHome();
		Animal a1 = new Cat();
		a1.eat();
		/**
		 * 由于a1具体指向的是Cat的实例,而不是Dog实例,这时将a1强制转成Dog类型,
		 * 将会发生	ClassCastException 异常,在转之前需要做健壮性判断。
             if(!Dog instanceof a1){ // 判断当前对象是否是Dog类型
                System.out.println("类型不匹配,不能转换");
                return;// 方法执行中止
             }
			Dog d1 = (Dog)a1;
			d1.catchMouse();
		*/
	}
}

向上转型

​ 不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作,这时就可以使用向上转型

向下转型

​ 当要使用子类特有功能时,就需要使用向下转型

好处:可以使用子类特有功能。

弊端:需要面对具体的子类对象;在向下转型时容易发生ClassCastException类型转换异常。在转换之前必须做类型判断。

多态 - 成员的特点

1. 子父类中出现同名的成员变量时,多态调用该变量时:

编译时期:参考的是所属的类的父类中是否有被调用的成员变量。没有,编译失败。

运行时期:参考的是所属的类的父类中的成员变量的值。

简单记编译运行都参考等号的左边。编译运行看左边。

2. 多态成员函数:

编译时期:参考子类对象的父类中没有该调用的函数,没有,编译失败

运行时期:参考子类有没有重写该方法,并运行子类对象成员函数

简而言之编译看左边,运行看右边。

3. 多态静态函数:

多态调用编译运行参考引用类型变量所属的类中的静态函数

简而言之编译运行看等号的左边。其实真正调用静态方法是不需要对象的,静态方法通类直接调用

结论:

  1. 对于成员变量静态函数编译运行都看左边。
  2. 对于成员函数编译看左边,运行看右边。

九、Object

Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。在对象实例化的时候,最终找的父类就是Object

Object类中常用的介绍

1. equals方法

equals方法,用于比较两个对象是否相同,它其实就是使用对象的内存地址在比较。Object类中的equals方法内部使用的就是比较运算符。

在开发中要比较两个对象是否相同,经常会根据对象中的特有数据进行比较,也就是在开发经常需要复写equals方法根据对象的特有数据进行比较。

/*
 *	描述人这个类,并定义功能根据年龄判断是否是同龄人
 *	由于要根据指定类的特有数据进行比较,这时只要覆盖Object中的equals方法
 *	在方法体中根据类的特有数据进行比较
 */
class Person extends Object{
	int age ;
	//复写父类的equals方法,实现自己的比较方式
	public boolean equals(Object obj) {
		//判断当前调用equals方法的对象和传递进来的对象是否是同一个
		if(this == obj){
			return true;
		}
		//判断传递进来的对象是否是Person类型
		if(!(obj instanceof Person)){
			return false;
		}
		//将obj向下转型为Perosn引用,调用其特有数据
		Person p = (Person)obj;
		return this.age == p.age;
	}
}

注意:在复写Object中的equals方法时,一定要注意public boolean equals(Object obj)的参数是Object类型,在调用对象特有数据时,一定要进行类型转换,在转换之前必须进行类型判断。

2. toString方法

toString()方法返回该对象的字符串表示,其实就是对象的类型+@+哈希值

由于toString()方法返回的结果是内存地址,在开发中经常需要按照对象的特定数据得到相应的表现形式,因此也需要复写它。

class Person extends Object{
	int age ;
	//根据Person类的特有数据复写toString方法
	public String toString() {
		return "Person [age=" + age + "]";
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值