家银们咱就是说一整个大总结好嘛🤔
前言
就整体而言,这一次的内部类和包装日期异常对我而言还是难度比较高的,并且不善于运用以及记忆的,所以在例题展示方面我会更注重多态和日期,因为对于内部类、异常的例题还是有些地方不理解。
继承&修饰符
概念
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法。
格式
格式:public class 子类名 extends 父类名{}
范例:public class Zi extends Fu{}Fu:是父类,也被称为基类、超类
Zi:是子类,也被称为派生类
子类的特点
- 子类可以有父类的内容
- 子类还可以有自己特有的内容
优缺点
好处:
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
弊端:
- 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
什么时候使用继承
继承体现的关系:is a
假设法:我有两个类A和B,如果他么满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承
举例:苹果和水果,猫和动物,猫和狗
变量的访问特点
在子类方法中访问一个变量,采用的是就近原则:
- 子类局部范围找
- 子类成员范围找
- 父类成员范围找
- 如果都没有就报错(不考虑父亲的父亲…)
成员方法的访问特点
通过子类对象访问一个对象
- 子类成员范围找
- 父类成员范围找
- 如果都没有就报错(不考虑父亲的父亲…)
super关键字
this&super关键字:
this:代表本类对象的引用
super:代表父类存储空间的标识(可以理解为父类对象引用)this和super的使用分别
(1) 成员变量
this.成员变量-访问本类成员变量
super.成员变量-访问父类成员变量
(2) 成员方法
this.成员方法-访问本类成员方法
super.成员方法-访问父类成员方法
(3) 构造方法:
this(…)-访问本类构造方法
super(…)-访问父类构造方法
构造方法的访问特点
子类中所有的构造方法默认都会访问父类中无参的构造方法,因为子类会继承父类中的数据,可能还会使用弗雷德数据。所以,子类初始化之前,一定要先完成父类数据的初始化,吗,每一个子类构造方法的第一条语句默认都是:super()
如果父类中没有无参构造方法,只有带参构造方法,该怎么办?
- 通过使用super关键字去显示的调用父类的带参构造方法
- 在父类中自己提供一个无参构造方法
方法重写
概述
子类中出现了和父类中一模一样的方法声明
应用
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容
@Override
帮助我们检查重写方法的方法声明的正确性
方法重写注意事项
- 私有方法不能被重写(父类私有成员子类是不能继承的)
- 子类方法访问权限不能更低(public > 默认(没有前面的,从void开始) > 私有)
- 返回值类型和形参不能变
final
概念
final关键字是最终的意思,可以修饰成员方法,成员变量,类
特点
修饰方法:表明该方法是最终方法,不能被重写
修饰变量:表明该变量是常量,不能再次被赋值
修饰类:表明该类是最终类,不能被继承
修饰局部变量
- 变量是基本类型:
final修饰指的是基本类型的数据值不能发生改变- 变量是引用类型:
final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
static
static关键字是静态的意思,可以修饰成员方法,成员变量
修饰的特点:
- 被类的所有对象共享(这也是我们判断是否使用静态关键字的条件)
- 可以通过类名调用(当然,也可以通过对象名调用)
访问特点:
- 非静态的成员方法:
1、能访问静态的成员变量
2、能访问非静态的成员变量
3、能访问静态的成员方法
4、能访问非静态的成员方法- 静态的成员方法:
1、能访问静态的成员变量
2、能访问静态的成员方法
继承例题解析
(1)定义一个ManKind类,包括
- 成员变量int sex和int salary;
- 方法void manOrWoman():根据sex的值显示“man”(sex == 1)或者“woman”(sex == 0);
- 方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
(2)定义类Kids继承ManKind,并包括
- 成员变量int yearsOld;
- 方法printAge()打印yearsOld的值。
(3)定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。
public class ManKind {
//创建属性
public int sex;
public int salary;
//无参构造
public ManKind() {
}
//有参构造
public ManKind(int sex, int salary) {
this.sex = sex;
this.salary = salary;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
//创建manOrWoman方法
public void manOrWoman() {
//根据题目中的条件给出if语句
if (sex == 1) {
System.out.println("man");
} else if (sex == 0) {
System.out.println("woman");
} else {
System.out.println("信息错误,请重新赋值");
}
}
//创建employeed方法,同样根据题目中的条件创建if语句
public void employeed() {
if(salary == 0) {
System.out.println("no job");
} else {
System.out.println("job");
}
}
}
多态&抽象类&接口
含义&前提
同一个对象,在不同时刻表现出来的不同形态
举例:
我们可以说猫是猫:猫 cat = new 猫 ( ) ;
我们也可以说猫是动物:动物 animal = new 猫 ( ) ;
这里猫在不同的时刻表现出来了不同的形态,这就是多态
多态的前提和体现
- 有继承/实现关系
- 有方法重写
- 有父类引用指向子类对象
成员访问特点
成员变量:编译看左边,执行看左边
成员方法:编译看左边,执行看右边
为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有
优缺点
好处:
- 提高了程序的扩展性
- 具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
弊端:
- 不能使用子类的特有功能
多态中的转型
分类
向上转型
从子到父 父类引用指向子类对象
向下转型
从父到子
父类引用转为子类对象
抽象类特点
- 抽象类和抽象方法必须使用abstract关键字修饰
public abstract class 类名 {}
public abstract void eat();- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能实例化
抽象类如何实例化呢?参照多态的方式,通过子类对象实例化,这叫抽象类多态- 抽象类的子类
要么重写抽象类中的所有抽象方法
要么是抽象类
抽象类的成员特点
- 成员变量 可以是变量 也可以是常量
- 构造方法 有构造方法,但是不能实例化
- 成员方法 可以有抽象方法:限定子类必须完成某些动作
接口
接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用 java种的接口更多的体现在对行为的抽象
接口特点
- 接口用关键字interface修饰
public interfae 接口名{}- 类实现接口用implements表示
public class 类名 implements 接口名 {}- 接口不能实例化
接口如何实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态
态的形式:具体类多态,抽象类多态,接口多态
多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象- 接口的实现类
要么重写接口中的所有抽象方法
要么是抽象类
接口的成员特点
- 成员变量
只能是常量
默认修饰符:public static final- 构造方法
接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在
一个类如果没有父类,默认继承自Object类- 成员方法
只能是抽象方法
默认修饰符:public abstract
类和接口的关系
- 类和类的关系
继承关系,只能单继承,但是可以多层继承- 类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口- 接口和接口的关系
继承关系,可以单继承,也可以多继承
抽象类和接口的区别
- 成员区别
抽象类
变量,常量;有构造方法;有抽象方法,也有非抽象方法 接口 常量;抽象方法- 关系区别
类与类
继承,单继承 类与接口 实现,可以单实现,也可以多实现 接口与接口 继承,单继承,多继承- 设计理念区别
抽象类
对类抽象,包括属性、行为 接口 对行为抽象,主要是行为
多态例题展示
应用继承和多态的思想,编写动物类,成员方法是动物叫声。
写三个具体的类(猫、狗、羊),它们都是动物类的子类,并重写父类的成员方法。
编写测试类,注意:随机产生三种具体动物,调用叫声这个方法
首先编写动物类,创建动物叫声方法,这里我输出的是“动物叫了”,容易分辨
public class Animal {
public void call() {
System.out.println("动物叫了");
}
}
这里是分别写的三个类,三个类都是要继承Animal,重写方法建议把输出的语句换成对应的类名动物叫,容易分辨
public class Cat extends Animal{
@Override
public void call() {
System.out.println("猫叫了");
}
}
public class Dog extends Animal{
@Override
public void call() {
System.out.println("狗叫了");
}
}
public class Sheep extends Animal{
@Override
public void call() {
System.out.println("羊叫了");
}
}
在测试类里面我们需要是随机产生三个动物然后调用方法,首先呢我们先创建Random随机数对象
然后再创建一个值为0的int类型数据,这一步旨在我们后面循环的时候给出范围,当这个值只<3的时候循环取内容(因为我们int数据的值定的0,所以<3也就是取值0.1.2,int值为1循环条件<4亦可)
首先我们要整体一个大循环while循环,条件就是当我们获得的动物数<3时,整体一直循环
Random随机数从0开始,所以我们需要再设置一个int值来接收随机数,范围就是0-3,取0不取3,所以我们需要+1
循环里面我们根据每个数值不一样选择的动物也不一样,所以选择switch语句,然后里面运用多态的形式来创建不同的动物调用方法,每一个下面都要++,来达到我们获得了动物这个操作,不然会一直无限循环
最后我们需要记得每个case结束写break,来结束这个操作进行下一个操作
import java.util.Random;
public class Test {
public static void main(String[] args) {
Random r = new Random();
int index=0;
while (index < 3) {
int b = r.nextInt(3)+ 1;
switch (b) {
case 1:
Animal a1 = new Cat();
a1.call();
index ++;
break;
case 2:
Animal a2 = new Dog();
a2.call();
index ++;
break;
case 3:
Animal a3 = new Sheep();
a3.call();
index ++;
break;
}
}
}
}
包装类&日期Api&异常
基本数据包装类
基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
Integer
Integer类概述
包装一个对象中的原始类型int的值
- public static Integer valueOf(int i):返回表示指定的int值的Integer实例
- public static Integer valueOf(String s):返回一个保存指定值的Integer对象String
代码展示
public class IntegerDemo {
public static void main(String[] args) {
// public static Integer valueOf(int i):返回表示指定的int值的Integer实例
Integer i1 = Integer.valueOf(100);
System.out.println(i1);
//public static Integer valueOf(String s):返回一个保存指定值的Ingeter对象String
Integer i2 = Integer.valueOf("100");
System.out.println(i2);
}
}
int和String的相互转换
- int转换为String
转换方式
方式一:直接在数字后加一个空字符串
方式二:public static String valueOf(int i):通过String类静态方法valueOf()
返回int参数的字符串表示形式。该方法是String类中的方法
代码展示
public class IntegerDemo {
public static void main(String[] args) {
//int --- String
int number = 100;
//方式1
String s1 = number + "";
System.out.println(s1);
//方式2
//public static String valueOf(int i)
String s2 = String.valueOf(number);
System.out.println(s2);
System.out.println("--------");
}
}
- String转换为int
转换方式
方式一:先将字符串数字转为Integer,再调用valueOf()方法
方式二:public static int parseInt(String s):通过Integer静态方法parseInt()进行转换
将字符串解析为int类型。该方法是Integer类中的方法
代码展示
public class IntegerDemo {
public static void main(String[] args) {
//String --- int
String s = "100";
//方式1:String --- Integer --- int
Integer i = Integer.valueOf(s);
//public int intValue()
int x = i.intValue();
System.out.println(x);
//方式2
//public static int parseInt(String s)
int y = Integer.parseInt(s);
System.out.println(y);
}
}
日期Api
Date
Date类概述
Date代表了一个特定的时间,精确到毫秒
Date类构造方法
- public Date()分配一个Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
- public Date(long date)分配一个Date对象,并将其初始化为表示从基准时间起指定的毫秒数
Date类常用方法
- public long getTime()获取的是日期对象从1970年1月1日00:00:00到现在的毫秒值
- public void setTime(long time)设置时间,给的是毫秒值
SimpleDate Format
SimpleDateFormat类概述
- SimpleDateFormat是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。
SimpleDateFormat类构造方法
- public SimpleDateFormat()构造一个SimpleDateFormat,使用默认模式和日期格式 public
- SimpleDateFormat(String pattern)构造一个SimpleDateFormat使用给定的模式和默认的日期格式
SimpleDateFormat类的常用方法
- 格式化(从Date到String)
- public final String format(Date date):将日期格式化成日期/时间字符串
- 解析(从String到Date)
- public Date parse(String source):从给定字符串的开始解析文本以生成日期
异常
编译时异常和运行时异常的区别
编译时异常
都是Exception类及其子类
必须显示处理,否则程序就会发生错误,无法通过编译 运行时异常
都是RuntimeException类及其子类
无需显示处理,也可以和编译时异常一样处理
throws和throw的区别
throws
- 用在方法声明后面,跟的是异常类名。
- 表示抛出异常,由该方法的调用者来处理
- 表示出现异常的一种可能性,并不一定会发生这些异常
throw
- 用在方法体内,跟的是异常对象名
- 表示抛出异常,由方法体内的语句处理
- 执行throw一定抛出了某种异常
try-catch方式处理异常
try {
可能出现异常的代码;
} catch(异常类名 变量名) {
异常的处理代码;
}
执行流程
- 程序从 try 里面的代码开始执行
- 出现异常,就会跳转到对应的 catch 里面去执行
- 执行完毕之后,程序还可以继续往下执行
日期Api例题展示
请使用日期时间相关的API,计算出一个人已经出生了多少天。
我们需要先创建Scanner键盘录入出生日期,以String类型接收创建对象。
然后我们用SimpleDateFormat来固定一个格式先,然后将其转换成Date形式,这个直接用方法就可以,sdf.parse,把我们键盘录入的数据转换成Date格式
现在就可以用long来获取从出生日期起到现在的毫秒数
我们再获取一个从初始时间到现在的毫秒数,用初始时间的减去出生日期到现在毫秒数就得到了这中间相隔天数的毫秒数最后输出的时候把时间/1000/60/60/24就可以得到天数
/*
请使用日期时间相关的API,计算出一个人已经出生了多少天。
*/
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class DateDemo {
public static void main(String[] args) throws ParseException {
//键盘录入出生日期
Scanner sc = new Scanner(System.in);
System.out.println("键盘输入出生日期(格式:yyyy-MM-dd):");
String birthday = sc.nextLine();
//然后用sdf把出生日期转换成Date形式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date birthdaytime = sdf.parse(birthday);
//然后用long获取生日到现在的毫秒数
long birthdayy = birthdaytime.getTime();
//再用long获取从初始时间到现在的毫秒数
long todaytime = new Date().getTime();
//然后用初始时间到现在的毫秒数减去生日到现在的毫秒数
long time = todaytime-birthdayy;
//输出的时候需要把时间/1000/60/60/24
System.out.println(time/1000/60/60/24);
}
}
总结
在这一关就是更新了一些知识,目前为止我了解到的还有一些解题的步骤有以下几点:
1、继承就是子类继承父类,用extends修饰,子类继承父类中的方法,子类还可以有自己特有的方法
2、抽象类用abstract修饰,是抽象类不一定有抽象方法,抽象方法的类一定是抽象类
3、多态,我的个人理解就是创造了一个父类,只要它有子类,就可以用多态创建出子类的对象
4、日期的方法,主要就是求两个日期之间相隔天数的问题,我理解的固有模板就是,我们创建SimpleDateFormat对象,给它设定一个固定的日期形式,然后Date对象 = sdf.parse(参数),转换成Date格式然后用long接收getTime方法得到的毫秒值,然后最后输出的时候就可以除数来得到天数或者年数
5、try…catch,固定格式就是try方法体里写抛出的异常,throw new xxxxxx;catch后面参数位置写异常和参数名抓住异常
以上就是本次总结,应该有对也有错,希望评论区欢乐留言纠错