1.final关键字
class Demo{
public static void main(String[] args) {
final int[] a=new int[]{1,2,3};
// a=new int[]{4,5,6}; 报错
a[0]=5;//可以,解释了final修饰引用性变量,变量存储的地址不能被改变,但地址所指向的对象的内容可以改变
}
}
什么是常量?
2.单例设计模式-懒汉式单例-饿汉式单例
3.枚举类
//常规写法
class Constant{
public static final int UP=0;
public static final int DOWN=1;
public static final int LEFT=2;
public static final int RIGHT=3;
}
class Demo{
public static void move(int direction){
switch (direction){
case Constant.UP:
System.out.println("向上移动");
break;
case Constant.DOWN:
System.out.println("向下移动");
break;
case Constant.LEFT:
System.out.println("向左移动");
break;
case Constant.RIGHT:
System.out.println("向右移动");
break;
default:
System.out.println("无效方向");
}
}
}
//枚举类写法,相较于常规的好处是
/*类型安全:枚举提供了更好的类型安全,因为它们限制了变量只能取预定义的值,而常规的静态常量类则没有这种限制。
可读性:枚举通常更易于阅读和理解,因为它们使用名称而不是数字或字符串来表示常量值。
维护性:使用枚举可以更容易地管理和维护一组相关的常量值,因为它们是集中定义的。
功能扩展:枚举可以有自己的方法和属性,这为扩展功能提供了可能,而常规的静态常量类则没有这样的能力。*/
enum Direction{
UP,DOWN,LEFT,RIGHT
}
class Demo2{
public static void move(Direction direction){
switch (direction){
case UP:
System.out.println("向上移动");
break;
case DOWN:
System.out.println("向下移动");
break;
case LEFT:
System.out.println("向左移动");
break;
case RIGHT:
System.out.println("向右移动");
break;
}
}
}
4.认识抽象类
5.模板方法设计模式
class A extends fu{
public void writemain(){
System.out.println("特殊方法A");
}
}
class B extends fu{
public void writemain(){
System.out.println("特殊方法B");
}
}
abstract class fu{
public final void write(){
System.out.println("公用方法1");
writemain();
System.out.println("公用方法2");
}
public abstract void writemain();
}
class Demo{
public static void main(String[] args) {
fu a=new A();
a.write();
}
}
/*
输出:
公用方法1
特殊方法A
公用方法2
*/
6.认识接口
//jdk 8之前,接口中只能定义常量和抽象方法
//接口不能创建对象
public interface A {
String STUDENT_NAME="li hua"; //接口中默认加上 public static final
// 等价于 public static final String STUDENT_NAME="li hua";
void run();//接口中给方法默认加上public abstract
//等价于 public abstract void run();
}
//Demo被称为实现类,可以同时实现多个接口,
//实现类实现多个接口必须重写全部抽象方法,否则必须定义成抽象类
public class Demo implements A{
@Override
public void run() {
}
}
public class Demo{
public static void main(String[] args) {
people p=new student();
doctor d=new student();
driver dr=new student();
}
}
interface driver{}
interface doctor{}
class student extends people implements driver,doctor{}
class people{}
接口的应用案例
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class Demo{
public static void main(String[] args) {
student[] s=new student[3];
s[0]=new student("li hua","boy",90);
s[1]=new student("zhang san","boy",100);
s[2]=new student("tu xin yue","girl",95);
tool t=new imp2(s);
t.listallinfo();
t.sumscore();
}
}
class student{
private String name;
private String sex;
private double score;
public student(String name, String sex, double score) {
this.name = name;
this.sex = sex;
this.score = score;
}
public student(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
interface tool{
public void listallinfo();
public void sumscore();
}
class imp1 implements tool{
private student[] s;
public imp1(student[] s){
this.s=s;
}
@Override
public void listallinfo() {
for(int i=0;i<s.length;i++){
System.out.println(s[i].getName()+" "+s[i].getSex()+" "+s[i].getScore());
}
}
@Override
public void sumscore() {
double sum=0;
for(int i=0;i<s.length;i++){
sum+=s[i].getScore();
}
System.out.println(sum/s.length);
}
}
class imp2 implements tool{
private student[] s;
public imp2(student[] s){
this.s=s;
}
@Override
public void listallinfo() {
int flag=0;
for(int i=0;i<s.length;i++){
System.out.println(s[i].getName()+" "+s[i].getSex()+" "+s[i].getScore());
if(s[i].getSex()=="boy"){
flag++;
}
}
System.out.println("男生人数:"+flag+"女生人数:"+(s.length-flag));
}
@Override
public void sumscore() {
double max=s[0].getScore();
double min=s[0].getScore();
double sum=0;
for(int i=0;i<s.length;i++){
sum+=s[i].getScore();
if(max<s[i].getScore()){
max=s[i].getScore();
}
if(min>s[i].getScore()){
min=s[i].getScore();
}
}
System.out.println("去掉一个最高分和最低分后的平均分为"+(sum-max-min)/(s.length-2));
}
}
7.JDK8开始,接口新增的三种方法
public class Demo{
public static void main(String[] args) {
A a=new impA();
a.run();
A.show();
}
}
class impA implements A{}
interface A{
//1.大部分情况下,接口只能写抽象方法,jdk8之后,可以写普通实例方法了,但必须加default修饰
//默认用public修饰
//但是接口不能构建对象,应该怎么调用该方法?利用接口的实现类的对象来调用
default void run(){
System.out.println("--run--");
go();
}
//2.jdk9开始支持私有方法,他是私有的,利用接口的实现类的对象也不能调用了,只能使用接口中的其他实例方法来调用
private void go(){
System.out.println("--go--");
}
//3.静态方法,默认用public方法,如何调用?只能通过接口名字直接调用
static void show(){
System.out.println("--show--");
}
}
8.接口的注意事项
//
public class Demo{
public static void main(String[] args) {
}
}
class D implements C{
@Override
public void show3() {}
@Override
public void show1() {}
@Override
public void show2() {}
}
interface A{
void show1();
}
interface B{
void show2();
}
interface C extends A,B{
void show3();
}
9.抽象类和接口的区别
相同点:
1.都是抽象形式,都可以抽象方法,都不能创建对象
2.都是派生子类形式,抽象类是被子类继承使用,接口是被实现类实现
3.一个类继承抽象类,或者实现接口,都必须重写玩他们的抽象方法,否则自己要成为抽象类不然会报错
4.都能支持多态,都能实现解耦合
不同点:
1.抽象类可以定义类的全部普通成员,接口只能定义常量和抽象方法(以及JDK8以后的三种新方法)
2.抽象类只能被类单继承,接口可以被类多实现
3.一个类继承抽象类就不能再继承其它类,一个类实现了接口还可以继承其他类或实现其他接口
4.抽象类体现模板思想,更利于做父类,实现代码的复用性
5.接口更适合做功能的解耦合,解耦合性更强更灵活。
6.设计目的
抽象类
主要用于代码复用和提供一个通用的模板。它体现了一种 “is - a” 的关系,即子类是一种特殊的抽象类。例如,Dog是一种Animal,Dog类可以继承Animal抽象类,复用Animal类中的属性和方法,同时实现自己特有的行为(如makeSound()方法实现狗叫)。
接口
用于定义行为规范,实现接口的类必须遵循这个规范。它体现了一种 “can - do” 的关系,即类可以做接口定义的事情。例如,如果一个类实现了Flyable接口,就表示这个类可以飞行,不管这个类是Bird还是Airplane,只要实现了Flyable接口,就必须实现fly()方法来定义飞行的行为。