Java面向对象笔记(待续)

面向对象的特征

目录

继承性

方法的重写

四种不同的权限修饰

super关键字

多态性

instanceof关键字

Object类的使用

JUnit单元测试

包装类(Wrapper)的使用

static关键字

理解main方法的语法

类的成员之四:代码块

final关键字

抽象类与抽象方法

接口(interface)

类的成员之五:内部类


1.继承性

继承(extends):public class 子类 extends 父类

Ctrl+T 查看继承结构

1.1 体现:一旦子类A继承父类B之后,子类A中就获取到了父类B中声明的结构、属性和方法

​ 特别的,父类中声明为private的属性和方法,子类继承父类之后,仍然认为获取了父类中私有的结构,只是因为封装性的影响,使得子类不能直接调用父类的结构而已

示例:

public class A extends B{}

**1.2 **子类继承父类之后,还可以声明自己特有的属性和方法,实现功能的拓展

1.3 子类和父类的关系:不同于子集和集合的关系

​ extends:延展 拓展

1.4 java中关于继承性的规定:

  • 一个子类只能有一个父类
  • **Java中类的单继承性:**一个类只能有一个父类
  • 子父类是相对的概念
  • 子类直接继承的 父类,称为直接父类;同理,间接继承的父类称为间接父类

1.5

  1. 如果没有显示的声明一个类的父类的话,此类继承于java.lang.Object类
  2. 所有的java类(除java.lang.Object类之外)都直接或间接继承于java.lang.Object类

继承性的好处

  • 减少代码冗余,提高代码复用性

  • 便于功能拓展

  • 多态的使用提供前提


2.方法的重写

概念

  1. 重写:子类继承父类之后,可以对父类中同名参数的方法,进行覆盖操作

  2. 应用: 重写之后,当创建子类对象,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法

  3. 重写的规定:

    ​ 方法的声明:

    权限修饰符 返回类型 方法名(形参列表){
        //方法体
    }
    

    要求

    1. 重写和被重写的方法名、形参列表要相同

    2. 子类重写的方法权限修饰符不小于父类被重写的方法权限修饰符

      ​ >特殊情况:子类不能重写父类中声明为private权限的方法

    3. 返回值类型:

      ​ >父类被重写的方法返回值类型是void,则子类重写的方法返回值类型只能是void

      ​ >父类被重写的方法返回值类型是A类型,则子类重写的方法返回值类型可以是A类或A类的子类

      ​ >父类被重写的方法返回值类型是基本数据类型(比如double),则子类重写的方法返回值类型必须是相同的基本数据类型

    4. 子类重写的方法抛出异常类型不大于父类被重写的方法


      子类和父类中的同名同参数的方法要么都声明为非static的,要么都声明为static的(不是重写)

在这里插入图片描述

重载(Overload)和重写(Override)的区别:


方法的重载和重写都是实现多态的方式
区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
重载对返回类型没有特殊的要求,不能根据返回类型进行区分

3.四种不同的权限修饰

在这里插入图片描述


4.super关键字

(1)理解
  1. super可以理解为:父类的
  2. super可以用来调用属性、方法、构造器
(2)使用方法
super.属性
super.方法
//显示调用父类中声明的属性或者方法
(3)使用情景
  • 子类和父类中定义了同名属性,想在子类中调用父类中生命的属性时,super.属性
  • 子类重写了父类的方法之后,调用父类中被重写的方法时,super.方法
(4)super调用构造器
  • 4.1 可以在子类的构造器中显式使用**“super(形参列表)”**的方式,调用父类中声明的指定构造器
  • 4.2 **“super(形参列表)”**的使用,必须声明在子类的首行!
  • 4.3 类的构造器中,针对**“this(形参列表)”或“super(形参列表)”**只能二选一,不能同时出现
  • 4.4 在构造器的首行,没有显示声明“this(形参列表)”和“super(形参列表)”,则默认调用父类中空参构造器super()
  • 4.5 在类的多个构造器中 至少有一个类中使用了“super(形参列表)”,调用父类中的构造器
(5)super调用构造器需要注意
  • this(形参列表): 本类重载的其他的构造器
  • super(形参列表): 调用父类中指定的构造器

5.多态性

(1)多态:父类的引用指向子类的对象(子类的对象赋给父类的引用)

理解:可以理解为一个事物的多种形态,可以直接用在抽象类和接口上

(2)多态的使用:当调用子父类同名同参数的方法,实际执行的是子类重写父类的方法–虚拟方法调用

​ 有了对象的多态性之后,编译期只能调用父类中声明的方法,但运行期实际执行的是子类重写父类的方法

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

前提:(1)类的继承关系 (2)方法的重写

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

在这里插入图片描述

(4)重载和多态的区别:

在这里插入图片描述

6.instanceof关键字

功能:实现父类调用子类特有属性和方法时的向下转型

使用方法 a instanceof A: 判断对象a是否是类A的实例。是 返回true;不是 返回false

使用情景:为了避免在向下转型时出现ClassCastException异常,所以要先进行instanceof判断,true则向下转型

public class Person extends Object {...}
public class Student extends Person {...}
public class Graduate extends Person {...}

public void method1(Person e) {
        if (e instanceof Person) 
        // 处理Person类及其子类对象
        if (e instanceof Student) 
        //处理Student类及其子类对象
        if (e instanceof Graduate)
        //处理Graduate类及其子类对象
}


7.Object类的使用

**定义:**Object类是所有Java类的根父类

如果在类的声明中未使用extends关键字指明其父类,则默认父类
为java.lang.Object类

public class Person {...}
//等价于:
public class Person extends Object {...}
//例:
method(Object obj){...} //可以接收任何类作为其参数
Person o=new Person();
method(o);

常用方法

  • equals方法

    /*
    *equals():所有类都继承了Object,也就获得了equals()方法。还可以重写。
    *只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象。
    */
    //格式:
    
    obj1.equals(obj2)
    
    /*特例:当用equals() 方法进行比较时,对类File 、String 、Date 及包装类(Wrapper Class)来说,
    *是比较类型及内容而不考虑引用的是否是同一个对象;
    *当自定义使用equals()时,可以重写。用于比较两个对象的“内容”是否都相等
    */
    

    ==和equals的区别(面试)

    在这里插入图片描述

toString()方法

toString()方法在Object类中定义,其返回值是String类型,返回类名和它
的引用地址。在进行String与其它类型数据的连接操作时,自动调用toString()方法

​ Object类中tostring()的定义:

public String ToStringTest(){
    return getClass().getname() + "@" + Integer.toHexString(hashCode());
}

8.JUnit单元测试

步骤

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

  2. 创建Java类,进行单元测试

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

  3. 此类中声明单元测试方法

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

  4. 此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;

  5. 声明好单元测试方法之后,就可以在方法体内测试相关的代码

  6. 写完代码以后,左键双击单元测试方法名,右键:run as -Junit Test

说明:

  1. 如果执行结果无异常:绿条
  2. 如果执行结果有异常:红条

9.包装类(Wrapper)的使用

总结:基本类型、包装类与String类间的转换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tMpgd8sS-1631816232629)(C:/Users/90584/AppData/Roaming/Typora/typora-user-images/image-20210916023405337.png)]

用法举例

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); //将字符串转换成数字

//包装类在实际开发中用的最多的在于字符串变为基本数据类型
String str1 = "30" ;
String str2 = "30.3" ;
int x = Integer.parseInt(str1) ; // 将字符串变为int型
float f = Float.parseFloat(str2) ; // 将字符串变为int型

10.static关键字

static: 静态的

(1)使用范围

​ 在Java类中,可用static修饰**属性、方法、代码块、内部类**

(2)使用static修饰属性:静态变量

​ 2.1 属性按是否使用static修饰分为:静态属性 vs 非静态属性**(实例变量)**

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

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

​ 2.2 static修饰属性的其他说明:

​ ① 静态变量随着类的加载而加载,可通过**“类.静态变量”**的方式进行调用

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

​ ③ 由于类只会加载一次,则静态变量在内存中也会存在一份(加入缓存):存在方法区的静态域中

​ ④ 类变量与实例变量

内存解析

在这里插入图片描述

类变量实例变量
yesno
对象yesyes

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

class Chinese{
    //非静态变量必须先构造对象才能调用
    String name;
    int age;
    static String nation;//静态变量 可直接以Chinese.nation调用而不用造对象
}

(3)使用static修饰方法:静态方法

​ ① 随着类的加载而加载,可以通过**“类.静态方法”**的方式进行调用

​ ②静态方法与非静态方法

静态方法非静态方法
yesno
对象yesyes

​ ③静态方法中,只能调用静态方法或属性

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

(4) static注意点

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

​ 4.2 关于静态属性和静态方法的使用,可以从生命周期的角度理解

(5) 开发中,如何确定一个属性、方法是否要声明为static的?

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

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

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

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

static应用举例

//static关键字的应用
public class CircleTest {
	public static void main(String[] args) {
		
		Circle c1 = new Circle();
		
		Circle c2 = new Circle();
		
		Circle c3 = new Circle(3.4);
		System.out.println("c1的id:" + c1.getId() );
		System.out.println("c2的id:" + c2.getId() );
		System.out.println("c3的id:" + c3.getId() );
		
		System.out.println("创建的圆的个数为:" + Circle.getTotal());
		
	}
}


class Circle{
	
	private double radius;
	private int id;//自动赋值
	
	public Circle(){
		id = init++;
		total++;
	}
	
	public Circle(double radius){
		this();
//		id = init++;
//		total++;
		this.radius = radius;
		
	}
	
	private static int total;//记录创建的圆的个数
	private static int init = 1001;//static声明的属性被所有对象所共享
	
	public double findArea(){
		return 3.14 * radius * radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}

	public int getId() {
		return id;
	}

	public static int getTotal() {
		return total;
	}

}

单例设计模式

/*
 * 单例设计模式:
 * 1. 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
 * 
 * 2. 如何实现?
 * 	 饿汉式  vs 懒汉式
 * 
 * 3. 区分饿汉式 和 懒汉式
 *   饿汉式:	
 *   	坏处:对象加载时间过长。
 *   	好处:饿汉式是线程安全的
 *   
 *   懒汉式:好处:延迟对象的创建。
 * 		  目前的写法坏处:线程不安全。--->到多线程内容时,再修改
 * 
 * 
 */
public class SingletonTest1 {
	public static void main(String[] args) {
//		Bank bank1 = new Bank();
//		Bank bank2 = new Bank();
		
		Bank bank1 = Bank.getInstance();
		Bank bank2 = Bank.getInstance();
		
		System.out.println(bank1 == bank2);
	}
}

//饿汉式
class Bank{
	
	//1.私有化类的构造器
	private Bank(){
		
	}
	
	//2.内部创建类的对象
	//4.要求此对象也必须声明为静态的
	private static Bank instance = new Bank();
	
	//3.提供公共的静态的方法,返回类的对象
	public static Bank getInstance(){
		return instance;
	}
}
//懒汉式
public class SingletonTest2 {
	public static void main(String[] args) {
		
		Order order1 = Order.getInstance();
		Order order2 = Order.getInstance();
		
		System.out.println(order1 == order2);
		
	}
}


class Order{
	
	//1.私有化类的构造器
	private Order(){
		
	}
	
	//2.声明当前类对象,没有初始化
	//4.此对象也必须声明为static的
	private static Order instance = null;
	
	//3.声明public、static的返回当前类对象的方法
	public static Order getInstance(){
		
		if(instance == null){
			
			instance = new Order();
			
		}
		return instance;
	}
	
}

11.理解main方法的语法

  1. main()方法作为程序的入口
  2. main()方法也是一个普通的静态方法
  3. main()方法可以作为我们与控制台交互的方式。(之前:使用Scanner)
public class MainTest {
	
	
	public static void main(String[] args) {//入口
		
		Main.main(new String[100]);
		
		MainTest test = new MainTest();
		test.show();
		
	}	
	public void show(){
		
	}
}


class Main{
		
	public static void main(String[] args) {
	
		for(int i = 0;i < args.length;i++){
			args[i] = "args_" + i;
			System.out.println(args[i]);
		}
		
	}
	
}

12.类的成员之四:代码块


13.final关键字


14.抽象类与抽象方法


15.接口(interface)


16.类的成员之五:内部类


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值