5.9~5.15学习情况

本文介绍了Java中的多态概念,包括其基本原理和使用场景,重点讲解了对象多态性、继承与方法重写的关系,以及如何通过实例化关键字和Object类进行操作。此外,文章还涵盖了静态属性与方法、final关键字的应用,以及JUnit单元测试和包装类的使用。单例模式设计和main方法的细节也被深入剖析。
摘要由CSDN通过智能技术生成

多态性

  1. 理解多态性:可以理解为一个事物的多种形态。(运行时行为)
  2. 何为多态性:

 

(或子类的对象赋给父类的引用)

  1. 多态的使用:à虚拟方法调用

有了对象的多态性以后,我们在编译期,只能调用父类的方法,但在运行期间,我们实际执行的是子类重写父类的方法。

   总结:编译,看左边;运行,看右边

  1. 多态性的使用前提:①类的继承关系  ②要有方法的重写

5.对象的多态性:只适用于方法,不适用于属性(编译和运行都看左边)

 

instanceof关键字的使用

a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。

使用情景:为了向下转型时出现ClassCastException的异常,我们在向下转型前,先进行instanceof的判断,一旦返回true,就进行向下转型;如果返回false,不进行向下转型。

如果 a instanceof A返回true,则a instanceof B也返回true

其中类B是类A的父类

Object类的使用

  1. Obiect类是所有Java类的根父类
  2. 如果再类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
  3. Object类中的功能(属性、方法)就具有通用性。

属性:无

方法:equals()/toString()/getClass()/hashCode()/clone()/finalize()/wait()、notify()、notifyAll()

  1. Object类只声明了一个空参构造器

面试题:==和equals()区别:

  • 回顾==的使用:

==:运算符

  1. 可以使用在基本数据类型变量和引用数据类型变量中
  2. 如果比较的是基本数据类型变量,比较两个变量的保存的数据是否相等。(不一定类型要相同)

如果比较的是引用类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。

补充:==符号使用时,必须保证符号左右两边的变量类型一致

  • equals()方法的使用:
  1. 是一个方法,而非运算符
  2. 只适用于引用数据类型
  3. Object类中equals()的定义:

 public boolean equals(Object obi) {

return (this  ==  obj);

说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。

  1. 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址值是否相同,而是比较两个对象的“实体内容”是否相同
  2. 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的“实体内容”是否相等。那么,我们就需要对Object类中的equals()进行重写

重写的原则:比较两个对象的实体内容是否相同

重写举例:

public boolean equals(Object obj){
    if(this == obj){//
判断当前的地址值是否和参数的地址值相同,若相同,那么两个

两个值一定相等
        return true;
    }
    if (obj instanceof Object){//
判断obj是否是Object的实例
        Order order =(Order)obj;//强制类型转换
        return this.orderId == order.orderId&&
                this.orderName.equals(order.orderName);
    }
    return  false;
}

 

Object类中toString()的使用:

  1. 当我们要输出一个对象的引用时,实际上就是调用当前对象的toString()
  2. Object类中的toString()的定义:

 

  1. 像String、Date、File、包装类等都重写了Object类中的toStirng()方法。

使得在调用对象的toString()时,返回“实体内容”信息

  1. 自定义类也可以重写toString()方法,当调用此方法时,返回对象的“实体内容”

Java中的Junit单元测试:

步骤:

  1. 选中当前工程 – 右键选择:build path – add libraries – Junit 4 – 下一步

创建Java类,进行单元测试。用于Eclipse

  1. 此时的Java类的要求:①此类时public的 ②此类提供公共的无参构造器
  2. 此类中声明单元测试方法。

此时的单元测试方法:方法的权限时public,没有返回值,没有形参

  1. 此单元测试方法上需要声明注释:@Test,并在单元测试类中导入:import org.junit.Test;
  2. 生命好单元测试方法以后,就可以在方法体内测试相关代码
  3. 写完代码以后,左键双击方法名,右键:run as – Junit Test

说明:

  1. 如果执行没有任何异常:绿条
  2. 如果执行结果异常:红条

包装类的使用:

  1. java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征

 

  1. 掌握基本数据类型、包装类、String三者之间的转换

 

  

 

 

关键字:static的使用

  1. static:静态的
  2. static可以用来修饰:属性、方法、代码块、内部类
  3. 使用static来修饰属性:静态变量,

3.1属性,按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)

        实例变量:我们创建了多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。

        静态属性:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,对导致其他对象调用此静态变量时,时修改过了的。

    3.2static修饰属性的其他说明:

         ①静态变量随着类的加载而加载。可以通过的“类.静态变量“的方式来调用

         ②静态变量的加载早于对象的创建。

         ③由于类只会加载一次,则静态变量在内存中也只会存在一份,存在方法区

           静态域中

         ④        类变量         实例变量

          类        yes               no

          对象      yes               yes

    3.3静态属性举例: System..out;Math.PI;

  1. 使用static修饰方法:静态方法
    • 随着类的加载而加载,可以通过的“类.静态变量“的方式来调用
    •        类变量         实例变量

类          yes               no

对象        yes               yes

    • 静态方法中,只能调用静态的方法或属性

非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性

  1. static注意点:

5.1在静态的方法内,不能使用this关键字、super关键字

5.2对于静态属性和静态方法的使用,从生命周期的角度理解

  1. 开发中,如何确定一个属性是否要声明为static的?

>属性是可以被多个对象所共享的,不会随着对象的不同而不同

>类中的常量也常常声明为static

开发中,如何确定一个方法是否要声明为static的?

>操作静态属性的方法,通常设置为static的

>工具类中的方法,习惯上声明为static的,比如,Math、Arrays、Collections

单例(Singleton)设计模式      

  • 所谓的类的单例设计模式,就是采取一定的方法保证再整个的软件系统中,对某个类只能存在一个对象实例:
  • 如何实现?
  1. 饿汉式单例模式的实现:

静态的方法中只能调用静态的属性

 

如下调用:

 

2.懒汉式单例模式的实现:

 

如下调用:

 

3.区分饿汉式和懒汉式

饿汉式:

坏处,对象加载时间过长。

    好处,饿汉式是线程安全的   

懒汉式:

好处,延迟对象的创建。

目前的写法坏处:线程不安全à到多线程内容时,再修改

4.单例模式设计模式的应用场景:

 

mian()方法的使用说明:

  1. main()方法作为程序的入口
  2. main()方法也是一个普通的静态方法
  3. main()方法也可以作为我们与控制台交互的方式。(之前:使用Scanner)

代码块(初始化块)

  1. 代码块的作用:

用来初始化类、对象

  1. 代码块如果有修饰的化,只能使用static
  2. 分类:静态代码块 vs 非静态代码块
  3. 静态代码块:

    >内部可以有输出语句

>随着类的加载而执行,而且只会执行一次

>作用:初始化类的信息

>如果一个类中定义了多个静态代码块,则按声明的先后顺序执行

>静态代码块的执行,优先于非静态代码块的执行

>静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构

  1. 非静态代码块:

>内部可以有输出语句

>随着对象的创建而执行

>没创建一个对象,就执行一次非静态代码块

>作用:可以在创建的时候,对对象的属性等进行初始化

>非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法

对属性可以赋值的位置:

    • 默认初始化
    • 显式初始化
    • 构造器中初始化
    • 有了对象以后,可以通过"对象.性"或"对象.方法"的方式,进行赋值
    • 在代码块中赋值

执行顺序:① - ② /⑤ - ③ - ④

final关键字的使用

在Java中声明类、属性和方法时,可使用关键字final来修饰。

  • final标记的类不能被继承;
  • final标记的方法不能被子类复写;
  • final标记的变量(成员变量或局部变量)即为常量,只能赋值一次。

final关键字修饰类、成员变量和成员方法

1.final

final用来修饰一个类,意味着该类成为不能被继承的最终类。出于安全性的原因和效率上的考虑,有时候需要防止一个类被继承。例如,Java类库中的String类,它对编译器和解释器的正常运行有着很重要的作用,不能轻易改变它,因此把它修饰为final类,使它不能被继承,这就保证了String类的惟一性。同时,如果你认为一个类的定义己经很完美,不需要再生成它的子类,这时也应把它修饰为final类。
定义一个
final类的格式如下:

  1. final class ClassName{ 
  2.     ... 
  3. } 

注意:声明为final的类隐含地声明了该类的所有方法为final方法。

下面的结论是成立的:声明一个类既为abstract,又为final是非法的,因为抽象类必须被子类继承来实现它的抽象方法。下面是一个final类的例子:

  1. final class A{ 
  2.     ... 
  3. } 
  4. class B extends A{//错误!不能继承
  5.     ... 
  6. } 

2.final修饰成员变量
变量被声明为
final后,成为常值变量(即常量),一旦被通过某种方式初始化或赋值,即不能再被修改。通常 staticfinal一起 使用来指定一个类常量。例如:

  1. static final int SUNDAY=0; 

final变量用大写字母和下划线来表示,这是一种编码规定。

3.final修饰成员方法
final修饰的方法为最终方法,不能再被子类重写,可以被重载。
尽管方法重写是Java非常有力的特征,但有时却需要避免这种情况的发生。为了不允许一个方法被重写,在方法的声明中指定
final属性即可。例如:

  1. class A{ 
  2.     final void method(){} 
  3. } 
  4. class B extends A{//定义A类的一个子类
  5.     void method(){}//错误,method()不能被重写 
  6. } 

该例中,因为method()方法在A中被声明为final,所以不能在子类B中被重写。如果这样做,将导致编译错误。
方法被声明为
final有时可以提高性能:编译器可以自由地内联调用它们,因为它“知道”它们不会被子类重写。

JDK 5.0 新特性:自动装箱和自动拆箱

自动装箱: 基本数据类型à包装类

int num = 2;

Interger in1 = num;//自动装箱

boolean b1 = true ;

Boolean b2 =b1;//自动装箱

自动拆箱:包装类à基本数据类型

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

int num3 = in1 ;//自动拆箱

面试题:

@Test


    public void test3(){
    Integer i =new Integer(1);
    Integer j = new Integer(1);
    System.out.println(i == j);//false

//Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],

//保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围//-128@127范围内,可以直接使用数组中的元素,不用再去new了。目的:提高效率
    Integer m = 1;//自动装箱
    Integer n = 1;
    System.out. println(m ==n);//true
    Integer x= 128;

Integer y = 128;
    System.out. println(x == y);//false

}

例题解析:

package com.test.exer;


import  java.util.Scanner;


import java.util.Vector;
/*
利用Vector代替数组处理。从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
提示。数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。
而向量类
java.util.vector可以根据需要动态伸缩。
创建
Vector对象:Vector v=new Vector();
给向量添加元素: v.addElement(0bject obj);   //obj必须是对象
职出向量中的元素
:Object obj=v.elementAt(0;
注意第一个元素的下标是0,返回值是Object类型的。
计算向量的长度
:v.size();
若与最高分相差10分内:A:20分内:B;
30
分内:C,其它:D
 */
public class ScoreTest {
    public static void main(String[] args) {
        //1.
实例化Scanner ,用于从键盘中获取学生成绩
       
Scanner scan = new Scanner(System.in);
        //2.
创建Vector对象:
       
// 创建Vector对象:Vector v=new Vector();相当于原来的数组
       
Vector v = new Vector();
        //3.
通过for(;;)或whiletrue)方式,
       
// Vector中添加数组:v.addElementObject obj
       
int maxScore = 0;
        for (; ; ) {
            System.out.println("
请输入学生成绩(输入负数代表结束)");
            int score = scan.nextInt();
            if (score < 0) {
                break;
            }
            if (score > 100) {
                System.out.println("
输入的数据非法,重新输入");
                continue;
            }
            //3.1
添加操纵:v.addElement(inScore);
            //JDK 5.0
之前:
//            Integer inScore = new Integer(score);
//            v.addElement(inScore);//
多态
           
//JDK 5.0 之后
           
v.addElement(score);//自动装箱
           
//4.获取当前成绩最大值
           
if (maxScore < score) {
                maxScore = score;
//                System.out.println("
最大值为:"+maxScore);
            }
        }
        //5.
遍历Vector,得到每个学生的成绩,并于
       
char level;
        for(int i = 0;i<v.size();i++){
            Object obj=v.elementAt(i);
            //jdk 5.0
之前:
//            Integer inScore = (Integer)obj;
//            int score = inScore.intValue();
            int score =(int)obj;
            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("student- "+i+",score is "+score +",level is"+level);
        }
        System.out.println("
最大值为:"+maxScore);
    }
}

本周完成的一些题目:

package com.exer;
/*
从键盘输入一串字符,输出有多少个不同的字符、每个字符出现的次数。
 */
import java.util.Scanner;
public class test {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        String str=input.nextLine();
        StringBuffer k=new StringBuffer(str);
        System.out.println(k);
        System.out.println("共有"+k.length()+"个字母!");
        String a;
        int index,sum;
        for(int i=0;i<k.length();) {
            sum=0;
            a=k.substring(0,1);
            index=k.indexOf(a);
            while(index!=-1) {
                sum++;
                k.deleteCharAt(index);
                index=k.indexOf(a,index);
            }
            System.out.println(a+"字母有"+sum+"个");
        }
    }
}
package com.test.exer2;
/*
*编写一个类实现银行账户的概念,包含的属性有""帐号”"、“"密码”、"存款余额”、"“利率”"、"最小余额"
* 定义封装这些同性的方法。账号要自动生成。
编写主类,使用银行账户类,输入、输出3个储户的上述信息。
* 考虑:哪些属性可以设计成static属性。
 */
public class Account {
    private int id;
    private String pwd = "000000";
    private double balance;
    private static double interestRate;
    private static double minMoney = 1.0;
    private static int init = 1001;//用于自动生成id使用
    public Account(){
        id = init++;
    }
    public Account(String pwd,double balance){
        id = init++;
        this.pwd = pwd;
        this.balance = balance;
    }
    public int getId() {
        return id;
    }
    public static double getInterestRate() {
        return interestRate;
    }
    public static void setInterestRate(double interestRate) {
        Account.interestRate = interestRate;
    }
    public static double getMinMoney() {
        return minMoney;
    }
    public static void setMinMoney(double minMoney) {
        Account.minMoney = minMoney;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public double getBalance() {
        return balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", pwd='" + pwd + '\'' +
                ", balance=" + balance +
                '}';
    }
}
package com.test.exer2;
/*
*编写一个类实现银行账户的概念,包含的属性有""帐号”"、“"密码”、"存款余额”、"“利率”"、"最小余额"
* 定义封装这些同性的方法。账号要自动生成。
编写主类,使用银行账户类,输入、输出3个储户的上述信息。
* 考虑:哪些属性可以设计成static属性。
 */
public class AccountTest {
    public static void main(String[] args) {
        Account acct1 =new Account();
        Account acct2 = new Account("123456",500);

        Account.setInterestRate(0.012);
        Account.setMinMoney(100);

        System.out.println(acct1);
        System.out.println(acct2);
    }
}
package com.ai;
import java.util.Scanner;
public class test1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();
        int flagenum = 0;
        for(int i = 0; i < s1.length(); i++) {
            for(int j = 0; j < s2.length(); j++){
                if(s1.charAt(i) != s2.charAt(j)){
                    break;
                }else {
                    if(j == s2.length() - 1)
                        flagenum++;
                    else
                        i++;
                }
            }
        }
        System.out.println(flagenum);
        sc.close();
    }
}
package com.ai;

import java.util.Scanner;

public class ObjectTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num1 = sc.nextInt();
        int num2 = sc.nextInt();
        // 在测试类中创建Demo类对象d1,传入输入值num1, d1调用toString方法并打印输出该值
        // 创建Demo类对象d2,同样传入输入值num1,打印判断d1和d2是否相等(实际是比较地址)
        /********* Begin *********/
        Demo d1 = new Demo(num1);
        d1.toString();
        Demo d2 = new Demo(num1);
        System.out.println(d1.equals(d2));
        /********* End *********/
        // 创建Person类对象p,传入输入值num2,打印判断d1和p是否相等(实际是比较地址)
        /********* Begin *********/
        Person p = new Person(num2);
        System.out.println(d1.equals(p));
        /********* End *********/
    }
}
class Demo {
    private int num;

    public Demo(int num) {
        this.num = num;
    }

    public boolean equals(Object obj) // Object obj = new Demo()
    {
        if (!(obj instanceof Demo)) // 判断obj是否和Demo是同类
            return false;
        Demo d = (Demo) obj; // 将父类的引用(Object)向下转换为子类(Demo)
        return this.num == d.num;
    }

    public String toString() {
        return "Demo:" + num; // 返回对象的值(每一个对象都有自己的特定的字符串)
    }
}

class Person {
    private int num;
    public Person(int num) {
        this.num = num;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值