四.面向对象(二)

转载自:Java笔记目录

2.1面向对象的特征二:继承性

引入类继承最基本的作用是:代码重用。

 

 

②语法

              [修饰符列表] class 子类名 extends 父类名{

                     类体;

              }

③子类继承父类以后,父类中声明的属性、方法,子类就可以获取到。

明确:当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接调用罢了,但是可以间接访问。子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分。构造方法无法被子类继承。

extends子类是对父类功能的“扩展”,明确子类不是父类的子集。

④java中类的继承性只支持单继承

一个类只能继承一个父类。反之,一个父类可以有多个子类。一个类如果没有显示的继承其他类,则该类默认继承Object,Object是SUN提供的java中的根类。

⑤子父类是相对的概念

Customer没有显示继承其他类,默认继承SUN提供的java.lang.Object;所有Customer类中也有toString方法.

public class Customer{

       public static void main(String[] args){

              Customer c = new Customer();

              String s = c.toString();

              System.out.println(s); //Customer@de6ced

       }

}

 

 

例子

/*

       账户类

              父类(超类,基类,superclass)

*/

public class Account{

       //账号

       private String actno;

       //余额

       double balance;

       //Constructor

       Account(){}

       Account(String actno,double balance){

              this.actno = actno;

              this.balance = balance;

       }

       //setter and getter

       public void setActno(String actno){

              this.actno = actno;

       }

       public String getActno(){

              return actno;

       }

}

/*

       信用账户

              子类(派生类,subclass)  

*/

public class DebitAccount extends Account{

       //信誉度

       double debit;

}

public class Test03{

       public static void main(String[] args){

              //创建信用卡对象

              DebitAccount da = new DebitAccount();

              //给信用卡账号赋值

              da.setActno("001"); //赋值

              //可以间接访问.

              System.out.println(da.getActno()); //读取

              //没有办法直接访问

              //System.out.println(da.actno);

       }

}

 

2.2方法的重写(覆盖)(override,orverwrite)

2.2.1 什么时候方法要进行重写?

如果父类中的方法已经无法满足当前子类的业务需求,需要将父类中的方法进行重新写一遍。就是要改变父类的行为。

注意:子类如果重写父类中的方法之后,子类对象一定调用的是重写之后的方法。

2.2.2 发生方法覆盖的条件

①发生在具有继承关系的两个类之间

②必须具有相同的方法名,相同的返回值类型,相同的参数列表.

③重写的方法不能比被重写的方法拥有更低的访问权限。

④重写的方法不能比被重写的方法抛出更宽泛的异常。(异常机制再讲。)

⑤私有的方法不能被覆盖。(多态之后讲)

⑥构造方法无法被覆盖。因为构造方法无法被继承。

⑦静态的方法不存在覆盖。(多态之后讲)

⑧覆盖指的是成员方法,和成员变量无关。

继承最基本的作用:代码重用。 继承最重要的作用:方法可以重写。

2.2.3 方法的重载与重写的区别

方法重载(Overload)的条件:

①方法名称相同

②方法参数类型、个数、顺序至少有一个不同

③方法的返回类型可以不同,因为方法重载和返回类型没有任何关系

④方法的修饰符可以不同,因为方法重载和修饰符没有任何关系

⑤方法重载只出现在同一个类中

方法覆盖(Override)的条件:

①必须要有继承关系

②覆盖只能出现在子类中,如果没有继承关系,不存在覆盖,只存在重载

③在子类中被覆盖的方法,必须和父类中的方法完全一样,也就是方法名,返回类型、参数列表,完全一样

④子类方法的访问权限不能小于父类方法的访问权限

⑤子类方法不能抛出比父类方法更多的异常,但可以抛出父类方法异常的子异常

⑥父类的静态方法不能被子类覆盖

⑦父类的私有方法不能覆盖

⑧覆盖是针对成员方法,而非属性

注意:两个方法要同为static或同为非static

public class Test01{

       public static void main(String[] args){

              //创建子类对象

              Cat c = new Cat();

              //调用方法

              c.move();

              Animal a = new Animal();

              a.move();

       }

}

//父类:动物

class Animal{

       //成员方法

       public void move(){

              System.out.println("动物在移动!");

       }

}

//子类:猫

class Cat extends Animal{

       //Cat的move方法应该输出:猫在走猫步!

       //Animal中的move方法已经无法满足Cat了。

       //所以要在Cat类中对Animal类中的move方法进行重新定义(方法的覆盖,方法的重写,Overwrite,Override)

       public void move(){

              System.out.println("猫在走猫步!");

       }

}

 

 

 

 

2.3 super关键字

①super不是引用类型,super中存储的不是内存地址,super指向的不是父类对象.

②super代表的是当前子类对象中的父类型特征。

③什么时候使用super?

 类和父类中都有某个数据,例如,子类和父类中都有name这个属性。如果要再子类中访问父类中的name属性,需要使用  super.

④super可以用在什么地方?

>super可以用在成员方法中,不能用在静态方法中。

> super可以用在构造方法中。

⑤super关键字用在构造方法中:

语法:

super(实参);

作用:通过子类的构造方法去调用父类的构造方法.

语法规则:一个构造方法第一行如果没有this(...);也没有显示的去调用super(...);系统会默认调用super();

注意

>super(...);的调用只能放在构造方法的第一行; super(....)和this(....)不能共存。super(...);调用了父类中的构造方法,但是并不一定会创建父类对象。java语言中只要是创建java对象,那么Object中的无参数构造方法一定会执行。

>尤其当子父类出现同名成员时,可以用super进行区分;super的追溯不仅限于直接父类; super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识。

⑦单例模式缺点:单例模式的类型无法被继承

super用在成员方法中:

//员工

public class Employee{

            String name = "张三";

           

            //成员方法

            public void work(){

                        System.out.println("员工在工作!");

            }

}

//经理

public class Manager extends Employee{

            String name = "李四";

            //子类将父类中的work方法重写了.

            public void work(){

                        System.out.println("经理在工作!");

            }

            //成员方法

            public void m1(){

                        //this.work();

                        //work();

                       

                        super.work();

                       

                        System.out.println(this.name);

                        System.out.println(name);

                        System.out.println(super.name);

            }

            /*

            //this和super相同,都不能用在静态上下文中。

            public static void m1(){

                        System.out.println(super.name);

            }

            */

}

super用在构造方法中:

//账户

public class Account extends Object{

            //Field

            private String actno;

            private double balance;

            //Constructor

            public Account(){

                        //super();

                        System.out.println("Account的无参数构造方法执行!");

            }

            public Account(String actno,double balance){

                        //super();

                        this.actno = actno;

                        this.balance = balance;

            }

            //setter and getter

            public void setActno(String actno){

                        this.actno = actno;

            }

            public String getActno(){

                        return actno;

            }

            public void setBalance(double balance){

                        this.balance = balance;

            }

            public double getBalance(){

                        return balance;

            }         

}

public class DebitAccount extends Account{

            //Field

            //独特属性

            private double debit;

            //Constructor

            public DebitAccount(){

                        //super();

            }

            public DebitAccount(String actno,double balance,double debit){

                        //通过子类的构造方法去调用父类的构造方法,作用是:给当前子类对象中的父类型特征赋值。

                        super(actno,balance);

                       

                        this.debit = debit;

            }

            //setter and getter

            public void setDebit(double debit){

                        this.debit = debit;

            }

            public double getDebit(){

                        return debit;

            }         

}

public class Test02{

           

            public static void main(String[] args){

                       

                        DebitAccount da = new DebitAccount();

                       

            }

}

单例模式的类无法被继承

//单例模式的类型没有子类。无法被继承.

 

//父类

public class Servlet{

           

            //构造方法私有

            private Servlet(){}  

}

//子类

class HttpServlet extends Servlet{

 

}

 

 

2.4子类对象实例化的全过程

public class TestDog {

       public static void main(String[] args) {

              Dog d = new Dog();

              d.setAge(10);

              d.setName("小明");

              d.setHostName("花花");

              System.out.println("name:" + d.getName() + " age:" + d.getAge()

                            + "hostName:" + d.getHostName());

              System.out.println(d.toString());

       }

}

//生物

class Creator {

       private int age;

       public int getAge() {

              return age;

       }

       public void setAge(int age) {

              this.age = age;

       }

       public Creator() {

              super();

              System.out.println("this is Creator's constructor");

       }

}

//动物类

class Animal extends Creator {

       private String name;

       public String getName() {

              return name;

       }

       public void setName(String name) {

              this.name = name;

       }

       public Animal() {

              super();

              System.out.println("this is Animal's constructor");

       }

}

//

class Dog extends Animal {

       private String hostName;

       public String getHostName() {

              return hostName;

       }

       public void setHostName(String hostName) {

              this.hostName = hostName;

       }

       public Dog() {

              super();

              System.out.println("this is Dog's constructor");

       }

}

 

2.5面向对象的特征三:多态性

2.5.1 关于java语言中的向上转型和向下转型

①向上转型(upcasting) :  子--->父(自动类型转换)

②向下转型(downcasting) :  父--->子(强制类型转换)

注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系。

public class Animal{

            //成员

            public void eat(){

              System.out.println("动物在吃!");

            }

}

public class Cat extends Animal{

            //重写

            public void eat(){

              System.out.println("猫吃鱼");

            }

            //Cat特有的方法.

            public void move(){

              System.out.println("猫走猫步!");

            }

}

public class Test02{

            public static void main(String[] args){

              //向上转型又被称作:自动类型转换.

              //父类型的引用指向子类型对象.

              //程序分两个阶段:编译阶段,运行阶段。

              //程序编译阶段只知道a1是一个Animal类型。

              //程序在运行的时候堆中的实际对象是Cat类型。

              Animal a1 = new Cat();

              //程序在编译阶段a1被编译器看做Animal类型.

              //所以程序在编译阶段a1引用绑定的是Animal类中的eat方法.(静态绑定)

              //程序在运行的时候堆中的对象实际上是Cat类型,而Cat已经重写了eat方法。

              //所以程序在运行阶段对象的绑定的方法是Cat中的eat方法.(动态绑定)

              a1.eat(); //猫吃鱼

              //向下转型:强制类型转换

              Animal a2 = new Cat(); //向上转型.

              //要执行move方法,怎么做?

              //只能强制类型转换,需要加强制类型转换符

              Cat c1 = (Cat)a2;

              c1.move();

              //判断以下程序运行的时候会出什么问题?

              //Animal a3 = new Dog(); //向上转型.

              //强制类型转换

              //Cat c2 = (Cat)a3; // java.lang.ClassCastException

              //在做强制类型转换的时候程序是存在风险的!

              //为了避免ClassCastException的发生,java引入了 instanceof

              /*

              用法:

                     1. instanceof运算符的运算结果是 boolean类型

                     2. (引用 instanceof 类型) --> true/false

                     例如:(a instanceof Cat) 如果结果是true表示:a引用指向堆中的java对象是Cat类型.

              */

              Animal a3 = new Dog();

              System.out.println(a3 instanceof Cat); //false

              //推荐:在做向下转型的时候要使用instanceof运算符判断,避免ClassCastException

              if(a3 instanceof Cat){

                     Cat c2 = (Cat)a3;

              }

            }

}

2.5.2 什么是多态

多态性,可以理解为一个事物的多种表型形态,是面向对象中最重要的概念,在java中有两种体现:

①方法的重载(overload)和重写(overwrite)。

子类对象的多态性:并不适用于属性。调用属性是就看”.”左边的对象。可以直接应用在抽象类和接口上。

2.5.3 子类对象的多态性使用的前提

①要有类的继承

②要有子类对父类方法的重写

补充:

程序运行分为编译状态和运行状态。

对于多态性来说,编译时,"看左边",将此引用变量理解为父类的类型;运行时,"看右边",关注于真正对象的实体:子类的对象。那么执行的方法就是子类重写的。

②Java引用变量有两个类型:编译时类型运行时类型

编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。若编译时类型和运行时类型不一致,就出现多态(Polymorphism

2.5.4 对象的多态

在Java中,子类的对象可以替代父类的对象使用

①一个变量只能有一种确定的数据类型

②一个引用类型变量可能指向(引用)多种不同类型的对象

Person p = new Student();

Object o = new Person();//Object类型的变量o,指向Person类型的对象

o = new Student(); //Object类型的变量o,指向Student类型的对象

 

③子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型(upcasting)。

④一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法。

Student m = new Student();

       m.school = “pku”;        //合法,Student类有school成员变量

       Person e = new Student();

       e.school = “pku”;   //非法,Person类没有school成员变量

//属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。

2.5.5 多态的好处

①使用多态可以使代码之间的耦合度降低。②项目的扩展能力增强。

例子:人喂养宠物

public class Person{//模拟主人

       /*

       public void feed(Dog d){ //喂养

              d.eat();

       }

       public void feed(Cat c){ //因为用户的业务改变了,所以软件要升级。

              c.eat();

       }

       */

       //以上的代码得出:Person类型的扩展能力太差。

    //尽量不要面向具体编程,面向父类型编程,面向抽象编程

       public void feed(Animal a){

              a.eat();

       }

}

public class Animal{

       public void eat(){}

}

public class Cat extends Animal{//宠物1

       public  void eat(){

              System.out.println("猫吃东西!");

       }

}

public class Dog extends Animal{//宠物2

       public  void eat(){

              System.out.println("狗吃东西!");

       }

}

public class Test{//多态测试

       public static void main(String[] args){

              //1.创建主人

              Person zhangsan = new Person();

              //2.创建宠物

              Dog d = new Dog();

              Cat c = new Cat();

              //3.喂

              zhangsan.feed(d);

              zhangsan.feed(c);

       }

}

2.5.6 虚拟方法调用(Virtual Method Invocation)

①正常的方法调用

Person e = new Person();

e.getInfo();

Student e = new Student();

e.getInfo();

虚拟方法调用(多态情况下)

Person e = new Student();

e.getInfo();     //调用Student类的getInfo()方法

编译时类型和运行时类型:

编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定

 

多态小结

1.前提:

  • 需要存在继承或者实现关系
  • 要有覆盖操作

2.成员方法:

  • 编译时:要查看引用变量所属的类中是否有所调用的方法。
  • 运行时:调用实际对象所属的类中的重写方法。

3.成员变量:不具备多态性,只看引用变量所属的类。

【记忆】

虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法。

例子:有一个舞池,规定只有人能进入,动物不能进,这时一个男人进去了,是以人的身份,但是跳舞的时候是一个男人的姿势!即调用的方法是那个实体的方法!

 

1)多态性的表现:①方法的重载与重写   ②子类对象的多态性

2)使用的前提:①要有继承关系 ②要有方法的重写

3)格式:

Person p = new Man();//向上转型

// 虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法

p1.eat();

p1.walk();

// p1.entertainment();

4)编译时,认为p是Person类型的,故只能执行Person里才有的结构,即Man里特有的结构不能够调用。子类对象的多态性,并不使用于属性。

5)关于向下转型:

   ①向下转型,使用强转符:()

   ②为了保证不报ClassCastException,最好在向下转型前,进行判断: instanceof

// 若a是A类的实例,那么a也一定是A类的父类的实例。

// 格式: 对象a instanceof 类A:判断对象a是否是类A的一个实例.是的话,返回true;否则返回false

       if (p1 instanceof Woman) {

                     System.out.println("hello!");

                     Woman w1 = (Woman) p1;

                     w1.shopping();

              }

              if (p1 instanceof Man) {

                     Man m1 = (Man) p1;

                     m1.entertainment();

              }

 

2.6 Object类

①java.lang.Object 类,是所有类的根父类!

②如果在类的声明中未使用extends 关键字指明其基类,则默认基类为Object 类

③Object类仅有一个空参的构造器  public Object(){  }

2.5.1 toString方法

SUN在Object类中设计toString方法的目的:返回java对象的字符串表示形式。

在现实的开发过程中,Object里边的toString方法已经不够用了。因为Object的toString方法实现的结果不满意。Object中的toString方法就是要被重写的。

SUN是这样实现toString方法的:

public String toString() {

                            return getClass().getName() + "@" + Integer.toHexString(hashCode());   

                  }

Object中的toString方法返回:类名@java对象的内存地址经过哈希算法得出的int类型值再转换成十六进制。

这个输出结果可以等同看做java对象在堆中的内存地址。

public class Test01{        

       public static void main(String[] args){

              //创建一个Object类型的对象.

              Object o1 = new Object();

              //调用toString方法.

              String oStr = o1.toString();

              System.out.println(oStr); //java.lang.Object@de6ced

              //创建一个Person类型的对象

              Person p1 = new Person("刘德华",50);

              //调用toString方法.

              String pStr = p1.toString();

              System.out.println(pStr); //重写前:Person@lfb8ee3//后:Person[name=刘德华,age=50]

              Person p2 = new Person("巩俐",50);

              System.out.println(p2.toString()); //Person[name=巩俐,age=50]

              //print方法后面括号中如果是一个引用类型,会默认调用引用类型的toString方法.

              System.out.println(p2); //Person[name=巩俐,age=50]

       }

}

class Person{

       String name;

       int age;

      

       Person(String name,int age){

              this.name = name;

              this.age = age;

       }

      

       //重写toString方法.

       //根据项目的需求而定。

       //需求规定,显示格式:Person[name=刘德华,age=50]

       public String toString(){

              return "Person[name="+name+",age="+age+"]";

       }

      

}

 

【eclipse操作】

快速生成重写的toString 方法:Source à Generate toString()…

 

2.6.2 equals方法

Object中的equals方法:

       public boolean equals(Object obj) {

                     return (this == obj);

           }

o1.equals(o2);  o1是this,o2是obj

== 两边如果是引用类型,则比较内存地址,地址相同则是true,反之则false.

Object中的equals方法比较的是两个引用的内存地址。

java对象中的equals方法的设计目的:判断两个对象是否一样。

public class Test01{

      

       public static void main(String[] args){

             

              Object o1 = new Object();

              Object o2 = new Object();

             

              boolean b1 = o1.equals(o2);

             

              System.out.println(b1); //false

             

             

              Star s1 = new Star(100,"黄晓明");

              Star s2 = new Star(100,"黄晓明");

              Star s3 = new Star(110,"黄晓明");

             

              System.out.println(s1.equals(s2)); //true

              System.out.println(s2.equals(s3)); //false

       }

}

 

class Star{

      

       //身份证号

       int id;

      

       //姓名

       String name;

      

       //Constructor

       public Star(int id,String name){

              this.id = id;

              this.name = name;

       }

       //Object中的equals方法比较的是内存地址.

       //在现实的业务逻辑当中,不应该比较内存地址,应该比较内容。

       //所以Object中的equals方法也要重写。

       //根据需求规定重写equals方法,

       //需求规定:如果身份证号一致,并且名字也一致,则代表是同一个人。

       //s1.equals(s2);

       public boolean equals(Object obj){

             

              if(this==obj) return true;

             

              if(obj instanceof Star){

                     Star s = (Star)obj;

                     if(s.id == id && s.name.equals(name)){

                            return true;

                     }

              }

             

              return false;

       }

}

/*

       关于java语言中如何比较两个字符串是否一致.

       在java中比较两个字符串是否一致,不能用“==”

       只能调用String类的equals方法.

*/

public class Test02{

       public static void main(String[] args){

              String s1 = new String("ABC");

              String s2 = new String("ABC");

             

              System.out.println(s1==s2); //false

             

              //String已经重写了Object中的equals方法,比较的是内容。

              System.out.println(s1.equals(s2)); //true

             

       }

}

 

【eclipse快捷方式】

快速生成重写的equals 方法:

 

Source àGenerate hashCode() and equals()…

 

2.6.3 finalize方法

垃圾回收器(Garbage Collection),也叫GC,垃圾回收器主要有以下特点:

①当对象不再被程序使用时,垃圾回收器将会将其回收

②垃圾回收是在后台运行的,我们无法命令垃圾回收器马上回收资源,但是我们可以

告诉他,尽快回收资源(System.gc 和Runtime.getRuntime().gc())

③垃圾回收器在回收某个对象的时候,首先会调用该对象的finalize 方法

④GC 主要针对堆内存

⑤单例模式的缺点

finalize方法什么时候调用?   

①finalize方法每个java对象都有

②finalize方法不需要程序员去调用,由系统自动调用。

③java对象如果没有更多的引用指向它,则该java对象成为垃圾数据,等待垃圾回收器的回收,垃圾回收器在回收这个java对象之前会自动调用该对象的finalize方法。

④finalize方法是该对象马上就要被回收了,例如:需要释放资源,则可以在该方法中释放。

public class Test01{

       public static void main(String[] args){

              Person p1 = new Person();

              p1 = null; //没有引用再指向它.等待回收.

              //程序员只能“建议”垃圾回收器回收垃圾.

              System.gc();

       }

}

class Person{

       //重写Object中的finalize方法.

       public void finalize() throws Throwable {

              System.out.println(this + "马上就要被回收了!");

              //让引用再次重新指向该对象,该对象不是垃圾数据,不会被垃圾回收器回收!

              //Person p = this;

       }

}

 

 

2.6.4 hashCode方法

public class Test01{

      

       public static void main(String[] args){

             

              //hashCode方法返回的是该对象的哈希码值

              //java对象的内存地址经过哈希算法得出的int类型的数值.

              Test01 t = new Test01();

             

              System.out.println(t.hashCode()); //14576877

             

       }

}

当垃圾收集器将要收集某个垃圾对象时将会调用finalize,建议不要使用此方法,因为此方法的运行时间不确定,如果执行此方法出现错误,程序不会报告,仍然继续运行。

public class FinalizeTest01 {

public static void main(String[] args) {

Person person = new Person();

person.id = 1000;

person.name = "张三";

//将person 设置为null 表示,person 不再执行堆中的对象

//那么此时堆中的对象就是垃圾对象

//垃圾收集(GC)就会收集此对象

//GC 不会马上收集,收集时间不确定

//但是我们可以告诉GC,马上来收集垃圾,但也不确定,会马上来,也许不会来

person = null;

System.gc();//通知垃圾收集器,来收集垃圾

/*

try {

Thread.sleep(5000);

}catch(Exception e) {

}

*/

}

}

class Person{

int id;

String name;

//此方法垃圾收集器会调用

public void finalize() throws Throwable {

System.out.println("Person.finalize()");

}

}

注意以下写法

public class FinalizeTest02 {

public static void main(String[] args) {

method1();

}

private static void method1() {

Person person = new Person();

person.id = 1000;

person.name = "张三";

//这种写法没有多大的意义,

//执行完成方法,所有的局部变量的生命周期全部结束

//所以堆区中的对象就变成垃圾了(因为没有引用指向对象了)

//person = null;

}

}

class Person{

int id;

String name;

public void finalize() throws Throwable {

System.out.println("Person.finalize()");

}

}

 

2.7包装类(Wrapper)

基本数据类型由于不是类,不能够使用java类库里提供的大量的方法。所有在设计上,我们让每一个基本数据类型都对应一个类,同时数据存储的范围还不变。此时相当于基本数据类型就具有了类的特点。针对八种基本定义相应的引用类型—包装类(wrapper 或封装类)。有了类的特点,就可以调用类中的方法。

 

 

2.7.1 装箱

基本数据类型包装成包装类的实例    ---装箱

通过包装类的构造器实现:

int i = 500;   Integer t = new Integer(i);

还可以通过字符串参数构造包装类对象:

Float f = new Float(“4.56”);

Long l = new Long(“asdf”);  //NumberFormatException

2.7.2 拆箱

获得包装类对象中包装的基本类型变量    ---拆箱

调用包装类的.xxxValue()方法:

boolean b = bObj.booleanValue();

JDK1.5之后,支持自动装箱,自动拆箱。但类型必须匹配。

2.7.3 字符串和基本数据类型的相互转换

①字符串转换成基本数据类型

通过包装类的构造器实现:

int i = new Integer(“12”);

通过包装类的parseXxx(String s)静态方法:

Float f = Float.parseFloat(“12.1”);

②基本数据类型转换成字符串

用字符串重载的valueOf()方法:

String fstr = String.valueOf(2.34f);

更直接的方式:

String intStr = 5 + “”

2.7.4 包装类用法举例

int i = 500;

Integer t = new Integer(i);

装箱:包装类使得一个基本数据类型的数据变成了类。

有了类的特点,可以调用类中的方法。

String s = t.toString(); // s = “500“,t是类,有toString方法

String s1 = Integer.toString(314); // s1= “314“  将数字转换成字符串。

String s2=“4.56”;

double ds=Double.parseDouble(s2);   //将字符串转换成数字

拆箱:将数字包装类中内容变为基本数据类型。

int j = t.intValue(); // j = 500,intValue取出包装类中的数据

包装类在实际开发中用的最多的在于字符串变为基本数据类型。

String str1 = "30" ;

String str2 = "30.3" ;    

int x = Integer.parseInt(str1) ;       // 将字符串变为int型

float f = Float.parseFloat(str2) ; // 将字符串变为int型

 

我们需要掌握的:

基本数据类型、包装类、String类之间的转换!

 

 

简易版:

①基本数据类型与对应的包装类有自动装箱、自动拆箱

如:int i = 10;

      Integer i1 = i;//自动装箱

      int j = i1;//自动拆箱

②基本数据类型、包装类---->String类:调用String类的重载的valueOf(Xxx xx);

  String类---->基本数据类型、包装类:调用相应的包装的parseXxx(String str);

注意:String str = "123";

         int i = (int)str;是错误的转法。

特别的Boolean类型的  赋值有误不会报异常,除了正确的返回true  其他一律返回false

代码:

package com.atguigu.java;

import org.junit.Test;

基本数据类型包装类String之间的相互转换

public class TestWrapper {

       //基本数据类型、包装类与String类之间的转换

       @Test

       public void test2(){

              //基本数据类型、包装类 --->String类:调用String类的重载的valueOf(Xxx x)方法

              int i1 = 10;

              String str1 = i1 + "";//"10"

              Integer i2 = i1;

              String str2 = String.valueOf(i2);

              String str3 = String.valueOf(true);//"true"

              str2 = i2.toString();

              System.out.println(str3);

              //String类--->基本数据类型、包装类:调用包装类的parseXxx(String str)方法

              int i3 = Integer.parseInt(str2);

              System.out.println(i3);

              boolean b1 = Boolean.parseBoolean(str3);

              System.out.println(b1);

              //int i4 = (int)str2;

       }

       //基本数据类型与包装类之间的转化

       @Test

       public void test1(){

              int i = 10;

              System.out.println(i);

              boolean b = false;

              //基本数据类型--->对应的包装类:调用包装类的构造器

              Integer i1 = new Integer(i);

              System.out.println(i1.toString());

             

              Float f = new Float("12.3F");

              System.out.println(f);

              //java.lang.NumberFormatException

              //i1 = new Integer("12abc");

              //System.out.println(i1);

              //对于Boolean来讲,当形参是"true"返回true,除此之外返回false。

              Boolean b1 = new Boolean("false");

              System.out.println(b1);

             

              b1 = new Boolean("truea");

              System.out.println(b1);

             

              Order o = new Order();

              System.out.println("$ "+o.b);//null

              //包装类--->基本数据类型:调用包装类Xxx的XxxValue()方法。

              int i2 = i1.intValue();

              System.out.println(i2);

              float f1 = f.floatValue();

              System.out.println(f1);

              boolean b2 = b1.booleanValue();

             

              //JDK5.0以后,自动装箱和拆箱

              int i4 = 12;

              Integer i3 = i4;//自动装箱

              Boolean bb = false;

             

              int i5 = i3;//自动拆箱

       }

}

class Order{

       Boolean b;

}

2.7.5 Junit单元测试类

eclipse快捷键】

快速生成Junit测试类:

当前工程上鼠标右键àBuild Pathà Add Libraries… à Junit à next à 选择Junit4àfinish

 

 

import org.junit.Test;

 

Junit单元测试类

①当前工程下-右键build path-add libraries-Junit4

②在主类中,创建一个空参的无返回值的方法,(如:public void test1())用于代码的测试,方法上声明:@Test

③导入import org.junit.Test;

④在test1()方法中,进行代码的编写。

⑤测试:双击方法名,右键run as-junit Test即可。

public class TestJunit {

       public static void main(String[] args) {

              String str = "AA";

              System.out.println(str);

       }

      

       @Test

       public void test2(){

             

       }

      

       @Test

       public void test1(){

              String str = "AA";

              System.out.println(str);

              m1();

       }

       public void m1(){

              System.out.println("hello world");

       }

}

2.7.6 包装类练习题

利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。

提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。而向量类java.util.Vector可以根据需要动态伸缩。

创建Vector对象:Vector v=new Vector();

给向量添加元素:v.addElement(obj);   //obj必须是对象

取出向量中的元素:Object  obj=v.elementAt(0);

注意第一个元素的下标是0,返回值是Object类型的。

计算向量的长度:v.size();

若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等

【代码】

package com.jiang.exer;

 

import java.util.Scanner;

import java.util.Vector;

public class TestScore {

       public static void main(String[] args) {

              //1.创建Scanner的对象,提示从键盘输入学生的成绩(以负数代表输入结束)

              Scanner s = new Scanner(System.in);

              System.out.println("请输入学生的成绩:(以负数代表输入结束)");

       //2.for(;;),从键盘依次获取学生的成绩,并填入由Vector v=new Vector()创建的对象v中。

              Vector v=new Vector();

              int maxScore = 0;//记录最高分

              for(;;){

                     int score = s.nextInt();

                     if(score < 0){

                            break;

                     }

                     //3.求出所有输入的正的成绩中的最高分

                     //获取学生成绩中的最高分

                     if(maxScore < score){

                            maxScore = score;

                     }

                     //依次将学生成绩村放入v中

                     Integer score1 = new Integer(score);

                     v.addElement(score1);

              }

              //4.通过v.elementAt(i)依次获取填入v中的元素,同时判断一下各个分数的等级并输出。

              for(int i = 0;i < v.size();i++){

                     Integer score = (Integer)v.elementAt(i);

                     char level;

                     if(maxScore - score <= 10){

                            level = 'A';

                     }else if(maxScore - score <= 20){

                            level = 'B';

                     }else if(maxScore - score <= 30){

                            level = 'C';

                     }else{

                            level = 'D';

                     }

                     System.out.println("学生成绩为:" + score + ",等级为:" + level);

              }

       }

}

 

posted @   mooyuu末鱼  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示