Java学习笔记===》9.面向对象进阶2

阅读: 评论:0

Java学习笔记===》9.面向对象进阶2

Java学习笔记===》9.面向对象进阶2

面向对象进阶

一、抽象类

1.抽象方法

共性的 行为(方法)抽取到父类之后,由于每一个子类执行的类容是不一样的,所以,在父类中不能确定具体的方法体,该方法就可以定义为抽象方法****

2.抽象类:

如果一个类中存在抽象方法,那么该类就必须声明为抽象类

3.抽象方法和抽象类的定义格式

(1)抽象方法的定义格式

public abstract 返回值类型 方法名 (参数列表){};

(2)抽象类的定义格式

public abstract class 类名{};

4.抽象类和抽象方法的注意事项

🔺抽象类不能实例化(不能创建对象)

🔺抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

🔺抽象类可以有构造方法

🔺抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法

package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test01;//有抽象方法的一定是抽象类
public abstract class Person {private String name;private int age;//抽象类中可以有构造方法(空参、含参)//这里的构造方法的作用:当创建子类对象时,给属性进行赋值的public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void work();//抽象类中不一定有抽象方法,public void sleep(){System.out.println("睡觉");   //抽象类中没有抽象方法不会报错}
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test01;//抽象类的子类要么是抽象类
//要么是重写抽象类中的所有方法
public  class Student extends Person {//重写所有方法public Student() {}public Student(String name, int age) {super(name, age);}@Overridepublic void work() {System.out.println("学生的工作i时学习");}
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test01;//抽象类的子类要么是重写所有方法,要么自己也是抽象类//这里抽象类的子类Teacher自己是 抽象类
//但是抽象类不能创建自己的对象
//如果要创建自己的类,就需要新建这个类的子类重写这个类的所有方法
public abstract class Teacher extends Person{
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test01;public class Test {public static void main(String[] args) {//1.抽象类不能(实例化)创建对象// Person p = new Person();  //Person是抽象的; 无法实例化Student s = new Student("zhangsan",22);System.out.Name()+","&#Age());}
}
abstract练习

需求:
青蛙frog 属性:名字,年龄 行为:吃虫子,喝水
狗dog 属性:名字,年龄 行为:吃骨头,喝水
山羊sheep 属性:名字,年龄 行为:吃草,喝水

package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test02;public abstract class Animal {private String name;private int age;public Animal() {}public Animal(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void eat();public void drink(){System.out.println("喝水");}
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test02;public  class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗在啃骨头");}public Dog() {}public Dog(String name, int age) {super(name, age);}
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test02;public  class Frog extends Animal {@Overridepublic void eat() {System.out.println("青蛙在吃虫子");}public Frog() {}public Frog(String name, int age) {super(name, age);}
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test02;public  class Sheep extends Animal {@Overridepublic void eat() {System.out.println("山羊在吃草");}public Sheep() {}public Sheep(String name, int age) {super(name, age);}
}
package com_03_mianxaingduixiang.Demo_06_Abstract.abstract_test02;
/*
需求:
青蛙frog          属性:名字,年龄    行为:吃虫子,喝水
狗dog             属性:名字,年龄    行为:吃骨头,喝水
山羊sheep         属性:名字,年龄    行为:吃草,喝水*/
public class Test {public static void main(String[] args) {Dog d = new Dog("大黄",12);Frog f = new Frog("小绿",4);Sheep s = new Sheep("肖恩",9);System.out.Name()+","&#Age());d.eat();d.drink();System.out.Name()+","&#Age());f.eat();f.drink();System.out.Name()+","&#Age());s.eat();s.drink();}
}

5.抽象类和抽象方法的意义

(1)疑问

把子类中共性的内容抽取到父类之后,由于方法体不确定,需要定义为抽象。子类使用时需要重写,但如果不抽取到父类中,直接写在子类里面不是更节约代码

★强制子类必须按照同一种格式进行重写(让代码格式统一)

二、接口

为什么会有接口?

接口:就是一种规则,是对行为的抽象

(1).接口的定义和使用

①接口关键字interface来定义

​ Public interface 接口名 { };

②接口不能实例化(不能创建对象)

③接口和类之间是实现关系,通过implements关键字表示

​ public class 类名 implements 接口名 { }

④接口的子类称为实现类

​ 在实现类中,要么重写接口中的所有抽象方法(使用更多),要么自身是抽象类

⑤注意:

(1)接口和类的实现关系,可以单实现,也可以多实现

​ public class 类名 implements 接口名1,接口名2 { };

(2)实现类还可以在继承一个类的同时实现多个接口

​ public class 类名 extends 父类 implements 接口名1,接口名2 { } ;

⑥接口练习

package com_03_mianxaingduixiang.Demo_07_inteface.interface_test01;public abstract class Animal {private String name;private int age;public Animal() {}public Animal(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void eat();}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test01;public interface swim {public abstract void swimming();
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test01;import jdk.swing.interop.SwingInterOpUtils;public class Dog extends Animal implements swim{public void swimming(){System.out.println("狗会狗刨");}public Dog() {}public Dog(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("狗在吃骨头");}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test01;public class Frog extends Animal implements swim {public void swimming(){System.out.println("青蛙会蛙泳");}@Overridepublic void eat() {System.out.println("青蛙吃虫子");}public Frog() {}public Frog(String name, int age) {super(name, age);}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test01;public class Rabbit extends Animal{@Overridepublic void eat() {System.out.println("兔子吃胡萝卜");}public Rabbit() {}public Rabbit(String name, int age) {super(name, age);}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test01;public class Test {public static void main(String[] args) {Rabbit r = new Rabbit("xiaobai",2);r.eat();Dog d = new Dog("dahuanug",3);d.eat();d.swimming();Frog f = new Frog("xiaolv",2);f.eat();f.swimming();}
}

(2)接口里面成员的特点

①成员变量

​ 接口中的成员变量只能是常量

​ 默认修饰符 : public static final

②构造方法

​ 接口中不能有构造方法

③成员方法

默认修饰符:public abstract

​ ★jdk7以前:接口中只能定义抽象方法

​ ★jdk8的新特性:接口中可以定义有方法体的方法

​ ★jkd9的新特性:接口中可以定义私有方法

(3)接口和类之间的关系

①类和类之间的关系

继承关系,只能单继承,不能多继承,但是可以多层继承

②类和接口的关系

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

③接口和接口的关系

继承关系,可以单继承,也可以多继承

细节:如果实现类实现了最下面的子接口的话,那么就需要重写所有的抽象方法

package com_03_mianxaingduixiang.Demo_07_inteface.interface_test04;
//接口1
public interface inter1 {public abstract void method1();
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test04;
//接口2
public interface inter2 {public abstract void method2();
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test04;
//接口3,继承了接口1和接口2
public interface inter3 extends inter1,inter2 {public abstract void method3();
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test04;
//实现类
public class Interimpl implements inter3{@Overridepublic void method3() {}@Overridepublic void method1() {}@Overridepublic void method2() {}
}

(4)JDK8 开始接口中新增的方法

1.JDK 7以前

接口中只能定义抽象方法

2.JDK 8的新特性

接口中可以定义有方法体的方法(默认、静态)

(1)默认方法

★允许在接口中定义默认方法,需要使用关键字default修饰

​ 🔺作用:解决接口升级的问题

★接口中默认方法的定义格式:

​ 🔺public default 返回值类型 方法名 (参数列表){…};

​ 🔺示例:public default void show(){…};

★接口中默认方法的注意事项;

​ 🔺默认方法不是抽象方法,所以不强制被重写,但如果被重写,重写的时候去掉default关键字

​ 🔺public 可以省略,但是default不可以省略

​ 🔺如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写

package com_03_mianxaingduixiang.Demo_07_inteface.interface_test07;public interface interB {//默认方法//如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写//两个接口中含有相同名字的方法,那么实现类里面就必须重写这个方法public default void show2(){System.out.println("interB接口中的默认方法------show2");}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test07;public interface interB {//默认方法//如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写//两个接口中含有相同名字的方法,那么实现类里面就必须重写这个方法public default void show2(){System.out.println("interB接口中的默认方法------show2");}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test07;public class interImpl implements interA,interB {@Overridepublic void show1() {System.out.println("重写之后的抽象方法show1");}//这里默认方法不重写也不会报错//但如果要重写就必须要去掉default关键字@Overridepublic void show2() {System.out.println("重写之后的默认方法show2");}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test07;
/*
★接口中默认方法的定义格式:🔺public  default  返回值类型  方法名  (参数列表){...};🔺示例:public  default  void  show(){...};★接口中默认方法的注意事项;🔺默认方法不是抽象方法,所以不强制被重写,但是如果被重写,重写的时候去掉default关键字🔺public 可以省略,但是default不可以省略🔺如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写*/
public class Test {public static void main(String[] args) {//创建实现类对象interImpl i1 = new interImpl();i1.show1();i1.show2();}
}
(2)静态方法

★允许在接口中定义静态方法,需要用static修饰

★接口中静态方法的定义格式:

​ 🔺格式:public static 返回值类型 方法名(){…};

​ 🔺示例:public static void show ( ) {…};

★接口中静态方法的注意事项:

​ 🔺静态方法只能通过接口名调用,不能通过实现类或者对象名调用

​ 🔺public 可以省略,但是static不可以省略

package com_03_mianxaingduixiang.Demo_07_inteface.interface_test08;public interface interA {//接口中的抽象方法public abstract void  method();//接口中的静态方法不能被重写public static void show(){System.out.println("interA接口中的静态方法-------show");}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test08;public class interImpl implements interA{@Overridepublic void method() {System.out.println("重写之后的method抽象方法");}public static void show(){System.out.println("实现类里面的静态方法----show");}
}
package com_03_mianxaingduixiang.Demo_07_inteface.interface_test08;import com_03_mianxaingduixiang.Demo_07_inteface.interface_test02.inter;/*
★允许在接口中定义静态方法,需要用static修饰
★接口中静态方法的定义格式:🔺格式:public  static  返回值类型  方法名(){...};🔺示例:public  static  void  show ( ) {...};
★接口中静态方法的注意事项:🔺静态方法只能通过接口名调用,不能通过实现类或者对象名调用🔺public 可以省略,但是static不可以省略*/
public class Test {public static void main(String[] args) {//调用接口中的静态方法interA.show();//调用实现类中的静态方法interImpl.show();//子类把从父类继承下来的虚方法表里面的方法进行覆盖了,这才叫重写}
}

3.JDK 9的新特性

接口中可以定义私有方法

定义私有方法,用来服务接口中的重复代码

(1)定义格式

①格式1:private vod show(){}

private void 方法名 (参数列表){ }

②private static void show () {}

private static 返回值类型 方法名(参数列表){}

4.总结:

(1)jdk7以前:接口中只能定义抽象方法

(2)jdk8:接口中可以定义有方法体的方法(默认、静态)

(3)jdk9:接口中可以定义私有方法

(4)私有方法分两种:

​ 1.普通的私有方法(给默认方法服务的)2.静态的私有方法(给静态方法服务的)

(5)接口的应用

1.接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了

2.当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态

​ 例如:public static void (interface A){}

(6)适配器设计模式

1.设计模式(Design Patern):

​ 是一套被反复利用、多打湖人只晓得、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性

简单理解:设计模式就是各种套路

2.适配器设计模式:

解决接口与接口实现类之间的矛盾问题

总结:

1.当一个接口中抽象方法过多,但是我们只要使用其中一部分的时候,就可以用适配器设计模式

2.书写步骤:

编写中间类 XXXAdapter,实现对应的接口

对接口中的抽象方法进行空实现(重写所有方法,但不写方法体)

让真正的实现类继承中间类,并重写需要用到的方法

为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰

三、内部类

1.什么是内部类:

在一个类的里面再定义一个类

public class Outer{  //外部类public  class Inner{		//内部类}
}
public class Test{		//外部其他类public  sattic void main(String []args){}
}

什么时候会用到内部类呢:

B类表示的事务是A类的一部分,且B单独存在没有意义

类的五大成员:属性、方法、构造方法、代码块、内部类

2.为什么要学习内部类:

需求:写一个JavaBean类描述汽车

属性:汽车的品牌,车龄,颜色,发动机的品牌,使用年限

public class Car{		//外部类String carname;int carAge;String carColor;//内部类表示的事务是外部类的一部分//且内部类单独出现没有任何意义class Engine{		//内部类String engineName;int EngineName;}
}

3.内部类的访问特点:

(1)内部类可以直接访问外部内的成员

(2)外部类要访问内部类的成员,必须要创建对象

package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test01;public class Car {String carName;int carAge;private String carColor;public void show2(){//外部类可以访问外部类的所有成员System.out.println(carAge+","+carName+","+carColor);//但不能直接访问内部类的成员,会报错//System.out.println(EngineName+","+EngineAge);//如果非要访问内部类的成员,就必须要创建对象Engine e = new Engine();System.out.println(e.EngineName+","+e.EngineAge);}class Engine {private String EngineName;int EngineAge;public void show(){//内部类可以直接访问外部类的成员,包括私有System.out.println(carAge+","+carName+","+carColor);//内部类也可以直接访问内部类里面的所有成员,包括私有System.out.println(EngineName+","+EngineAge);}}
}

4.成员内部类

(1)成员内部类的代码如何书写

★ 成员内部类是写在成员位置的,属于外部类的成员(类中方法外)

★成员内部类可以被一些修饰符所修饰,比如:private(本类里面)、默认(本包下的所有子类)、protected(本包或其他包的子类里面)、public(所有位置)、static等

★在成员内部类的里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量

public class Car{		//外部类String carname;int carAge;String carColor;class Engine{		//成员内部类String engineName;int EngineName;}
}

(2)如何创建成员内部类的对象

①在外部内中编写方法,对外提供内部类的对象

使用场景:当内部类被private修饰时,在外部类编写方法,对外提供内部类对象

②可以在外部类直接创建:当成员内部类被非私有修饰时直接创建

外部类名.内部类名. 对象名 = 外部类对象.内部类对象;

package com_03_mianxaingduixiang.InnerClass_test02;public class Outer {private class Inner{//在内部类里面声明静态变量//但是在JDK16之前不能在内部类里面声明静态变量//static int a = 10;}//当内部类是私有的时候,可以在外部类里面内部类外面创建创建方法,对外提供内部类对象public Inner getInstance(){return new Inner();}
}
package com_03_mianxaingduixiang.InnerClass_test02;public class Test {public static void main(String[] args) {//创建对象的方式//类名.对象名 = new 类名();//Student s = new Stutdent();//我要创建的是谁的对象===》内部类的对象//如何创建成员内部类的对象//①在外部内中编写方法,对外提供内部类的对象//②可以在外部内直接创建内部类对象:// 外部类名.内部类名. 对象名 = 外部类对象   .成员内部类对象;//  Outer .Inner      oi = new Outer().new Inner();  内部类私有的时候不能直接创建对象Outer o = new Outer();//调用方法,获取内部类的对象System.out.Instance());}
}

(3)成员内部类如何获取外部类的成员变量

package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test03;public class Outer {private int a = 10;class Inner{private int a = 20;public  void  show(){int a = 30;Outer o1 = new Outer();System.out.println(this.a);     //20System.out.println(a);          //30System.out.println(o1.a);        //10//Outer.this:表示获取了外部类对象的地址值System.out.println(Outer.this.a);   //10}}
}
package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test03;public class Test {public static void main(String[] args) {Outer.Inner oi = new Outer().new Inner();oi.show();}
}

(4)总结:

①内部类的分类

成员内部类、静态内部类、局部内部类、匿名内部类

②什么是成员内部类

写在成员位置的,属于外部类的成员

③获取成员内部类对象的两种方式

​ 方式一:当成员内部类被private修饰时,在外部类中编写方法,对外提供内部类对象

​ 方式二:当成员内部类被非私有修饰时,直接创建对象

​ 外部类 . 内部类 对象名 = new 外部类(). new内部类();

​ Outer . Inner oi = new Outer . new Inner();

④外部类成员和内部类成员变量重名时,在内部类如何访问

​ System.out.println( Outer . this . 变量名);

5.静态内部类

静态内部类只能访问外部类中的静态变量和静态方法,如果像访问非静态的需要创建外部类的对象

public class Outer{		//外部类String name;int Age;int colorstatic class Inner{	//静态内部类String name;int Age;}
}

1.静态内部类

(1)创建静态内部类的对象

外部类名 . 内部类名 对象名 = new 外部类名 . 内部类名();(要和非静态的创建对象区分)

(2)调用非静态方法的格式

先创建对象,用对象调用

(3)调用静态方法的格式

外部类名 . 内部类名 . 方法名();

package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test04;public class Outer {int a = 10;static int b = 20;//静态内部类static class Inner{public void show1(){Outer o = new Outer();System.out.println(o.a);System.out.println(b);System.out.println("非静态的方法被调用了");}public static void show2(){Outer o = new Outer();System.out.println(o.a);System.out.println(b);System.out.println("静态的方法被调用了");}}
}
package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test04;import javax.annotation.processing.SupportedAnnotationTypes;public class Test {public static void main(String[] args) {Outer.Inner oi = new Outer.Inner();oi.show1();//虽然也可以直接调用静态方法,但是不提倡//oi.show2();Outer.Inner.show2();}
}
(4)总结
(1)什么是静态内部类

静态内部类是一种特殊的成员内部类

(2)直接创建静态内部对象的方式

Outer .Inner oi = new Outer.Inner();

外部类名 . 内部类名 对象名 = new 外部类名 . 内部类名();

(3)如何调用静态内部类中的方法?

​ 静态内部类只能访问外部类中的静态变量和静态方法

​ 如果想访问非静态的需要创建外部类的对象

非静态方法:先创建对象,用对象调用

静态方法:外部类名 . 内部类名 . 方法名();

6.局部内部类

(1)什么是局部内部类

​ 将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量

(2)局部内部类的特点

​ 外界无法直接使用,需要在方法内部创建对象并使用

​ 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test05;/*将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量外界无法直接使用,需要在方法内部创建对象并使用该类可以直接访问外部类的成员,也可以访问方法内的局部变量*/
public class Outer {int b = 20;public void show1(){int a = 10;//局部内部类class Inner{String name;int age;public void show2(){//局部内部类可以直接访问外部类的成员和局部变量System.out.println(b);  //成员变量System.out.println(a);  //局部变量System.out.println("局部内部类中的show2方法");}//jdk16之后可以定义静态//public static void show3(){public static void show3(){System.out.println("局部内部类中的show2方法");}}//在方法里面创建局部内部类的对象Inner i = new Inner();System.out.println(i.name+","+i.age);//创建对象调用局部内部类里面的方法i.show2();i.show3();//使用类名调用静态方法Inner.show3();}
}
package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test05;public class Test {public static void main(String[] args) {//外界无法直接使用局部内部类,需要在方法内部创建对象并使用//无法直接使用show方法里面的局部变量aOuter o = new Outer();o.show1();}
}

7.匿名内部类

(1)什么是匿名内部类

🔺匿名内部类本是上就越是隐藏了名字的内部类,这个内部类可以写在成员位置,也可以写在局部位置,只不过名字被隐藏了

(2)格式

	new 类名或者接口名(){	//类名表示继承关系,接口表示实现关系重写方法};

🔺格式的细节:这个格式里面包含了三部分:继承/实现 、方法重写 、创建对象

例如:

new Inter(){public void show(){}
}

(3)使用场景

①当方法的参数是接口或者类时

②以接口为例,可以传递这个接口的实现类对象

③如果实现类只要使用一次,就可以用匿名内部类简化代码

代码演示:

package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test06;public class Test {public static void main(String[] args) {//编写匿名内部类的代码new Swim(){@Overridepublic  void swim(){System.out.println("重写之后的swim方法");}};}
}
package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test06;public interface Swim {public abstract void swim();
}

扩展:

package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test06;public class Test {public static void main(String[] args) {//编写匿名内部类的代码new Swim(){@Overridepublic  void swim(){System.out.println("重写之后的swim方法");}};method(new Animal(){@Overridepublic void eat(){System.out.println("狗吃骨头");}});
//        new Animal(){
//            @Override
//            public void eat(){
//                System.out.println("重写之后的eat方法");
//            }
//        };}public static void method(Animal a){}
}
package com_03_mianxaingduixiang.Demo_08_InnerClass.InnerClass_test06;public class Test2 {public static void main(String[] args) {//匿名内部类的格式
//        new 类名(继承关系)/接口(实现关系)(){
//            重写方法
//        }//这个整体可以理解为Swim接口实现类的对象Swim s = new Swim(){@Overridepublic void swim() {System.out.println("重写之后的swim方法");}};//编译看左边,运行看右边,对象调用方法s.swim();//匿名实现类整体是是一个对象,所以可以调用方法new Swim(){@Overridepublic void swim() {System.out.println("重写游泳方法");}//用整体来调用方法}.swim();}
}

四、拼图小游戏

1.目的

(1)将面向对象的知识点贯穿起来(循环、字符串、判断、集合)

(2)锻炼逻辑思维能力

(3)知到所学知识点在实际开发中的应用场景

涉及到的知识点;

封装、继承、多态、抽象类、接口、内部类、集合、字符串、数组、循环、判断

2.游戏主界面添加组件

(1)JFrame:(主窗体)

(2)JMenuBar:菜单

(3)JMenu:菜单选项

(4)JLabel:容器管理(文字、图片等)

3.事件

(1)定义:

就是可以被组件识别的操作,也就是当我们对组件干了某件事之后,就会执行相应的代码

(2)事件的核心要素

①事件源:按钮、图片、窗体

②事件:指某些操作鼠标点击、鼠标划入

③绑定监听:当事件源上发生了某个事件,则会执行某些代码

(3)常见的事件监听

①KeyListener:键盘监听

Modifier and Type方法描述
voidkeyPressed ( KeyEvent e )按下键时调用
voidkeyReleased ( KeyEvent e )当键已被释放时调用
voidkeyTyped ( KeyEvent e )键入键时调用

**细节1:**如果我们按下一个按键没有松开,那么会重复的去调用keyPressed方法

**细节2:**键盘里面众多案件,如何进行区分?

​ 每一个按键都有一个编号与之对应,调用方法e.getKeyCode()可以获取到每一个按下的按键的编号

package st;import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;public class MyJFrame3 extends JFrame implements KeyListener {public MyJFrame3 (){//设置界面的宽高this.setSize(603,688);//设置界面的标题this.setTitle("我的界面");//设置界面置顶this.setAlwaysOnTop(true);//设置界面居中this.setLocationRelativeTo(null);//设置关闭模式this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件this.setLayout(null);//给整个窗体添加键盘监听//调用者this:表示本类对象,就是当前的界面对象,表示我要给整个页面添加监听//addKeylistener :表示要给本界面添加键盘监听//参数this : 表示当事件被出发之后,会执行本类中的对应代码this.addKeyListener(this);//显示界面this.setVisible(true);}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {System.out.println("按下不松");}@Overridepublic void keyReleased(KeyEvent e) {System.out.println("释放");//e.getKeyCode() : 获取键盘上每一个按键的编号 与ASCII码表没有关系int code = e.getKeyCode();System.out.println("按下的按键是"+code);if (code == 65){System.out.println("现在按的是A");}else if (code == 66){System.out.println("现在按的是B");}}
}

②MouseListener:鼠标监听机制

划入动作

按下动作

松开动作

划出动作

如果想监听一个按钮的单击事件,有以下三种方式

★动作监听★鼠标监听中的单击事件★鼠标监听中的松开事件★

package st;import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;public class MyJFrame2 extends JFrame implements MouseListener {//创建一个按钮对象JButton jbt1 = new JButton("点我改变大小");//创建一个按钮对象JButton jbt2 = new JButton("点我改变位置");public MyJFrame2 (){//设置界面的宽高this.setSize(603,688);//设置界面的标题this.setTitle("我的界面");//设置界面置顶this.setAlwaysOnTop(true);//设置界面居中this.setLocationRelativeTo(null);//设置关闭模式this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件this.setLayout(null);//给按钮设置宽高jbt1.setBounds(0,0,100,50);//给按钮绑定鼠标事件jbt1.addMouseListener(this);//给按钮设置宽高jbt2.setBounds(100,0,100,50);//给按钮添加事件jbt2.addMouseListener(this);//显示界面this.setVisible(true);//将按钮添加到窗体中ContentPane().add(jbt1);ContentPane().add(jbt2);}@Overridepublic void mouseClicked(MouseEvent e) {System.out.println("这是个单击事件");}@Overridepublic void mousePressed(MouseEvent e) {System.out.println("这是个按下不松事件");}@Overridepublic void mouseReleased(MouseEvent e) {System.out.println("这是个松开事件");}@Overridepublic void mouseEntered(MouseEvent e) {System.out.println("这是个划入事件");}@Overridepublic void mouseExited(MouseEvent e) {System.out.println("这是个划出事件");}
}
方法摘要
Modifier and type方法描述
voidmouseClicked(MouseEvent e)在组件上单击(按下并释放)鼠标按钮时调用
voidmouseEntered(MouseEvent e)当鼠标进入组件时调用
voidmouseExited(MouseEvent e)当鼠标退出组件时调用
voidmousePressed(MouseEvent e)在组件上按下鼠标按钮时调用
voidmouseReleased(MouseEvent e)在组件上释放鼠标按钮时调用

③ActionListener:行为(动作)监听

package st;import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;public class MyJFrame extends JFrame implements ActionListener{//创建一个按钮对象JButton jbt1 = new JButton("点我改变大小");//创建一个按钮对象JButton jbt2 = new JButton("点我改变位置");public MyJFrame() {//设置界面的宽高this.setSize(603,688);//设置界面的标题this.setTitle("我的界面");//设置界面置顶this.setAlwaysOnTop(true);//设置界面居中this.setLocationRelativeTo(null);//设置关闭模式this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件this.setLayout(null);//给按钮设置宽高jbt1.setBounds(0,0,100,50);//给按钮添加事件jbt1.addActionListener(this);//给按钮设置宽高jbt2.setBounds(100,0,100,50);//给按钮添加事件jbt2.addActionListener(this);//显示界面this.setVisible(true);//将按钮添加到窗体中ContentPane().add(jbt1);ContentPane().add(jbt2);}@Overridepublic void actionPerformed(ActionEvent e) {//对当前按钮进行判断//获取当前被操作的按钮的对象Object source = e.getSource();if (source == jbt1){jbt1.setSize(200,200);}else if (source == jbt2){Random r = new Random();jbt2.Int(500),r.nextInt(500));}}
}
美化界面

本文发布于:2024-01-29 16:50:26,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170651822816763.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23