三周
1. this关键字
- 一般写在实体类中,表示当前对象
- 可以用this调用方法和属性
- 调用构造方法 (一定是在一个 构造方法内调用另一个),必须放在构造方法的第一行
练习This调用属性和方法,在其他构造方法中调用构造方法
2. 方法是一个类对象
方法的参数可以是八大基本数据类型,String, 数组
类也可以作为一个对象的参数
3. 多类合作
一个类对象可以作为另一个类的属性
//创建成年人类 class Adult{ private String name; private Child child;//把孩纸类作为属性 public void setName(String name){ this.name = name; } public String getName(){ return name; } public void setName(Child child){ this.child = child; } public String getChild(){ return child; } } //创建孩子类 class Child{ private String name; Private Toy toy; public void setName(String name){ this.name = name; } public String getName(){ return name; } public void setToy(Toy toy){ this.toy = you; } public String getToy(){ return toy; } } //创建玩具类 class Toy{ private String name; private double price; public void setName(String name){ this.name = name; } public String getName(){ return name; } public void setPrice(double price){ this.price = price; } public String getPrice(){ return price; } } public class Dome{ public static void main(String[] args){ //创建玩具对象 Toy toy = new toy(); //创建孩纸对象 Child child = new Child(); //创建成年人对象 Adult adult = new Adult(); //对玩具属性赋值 toy.setName("挖掘机"); toy.setPrice(20); //对孩纸属性赋值 child.setName("JJ"); child.setToy(toy); //对成年人进行赋值 adult.setName("JJJ"); adult.setChild(child); //取值 //玩具挖掘机 System.out.println("玩具:"+adult.getChild().getToy().getName()); //成年人名字 System.out.println("成年人名字:"+aduilt.getName()); } }
4. 继承
Java三大特性之一(封装,继承,多态)
语法格式 (关键词:extends)
class A { 属性; 方法; } class B extends A{ super; }
特点 :
父类的公开的(public)和默认的属性可以被子类继承时使用,(私有化的private 不可以)
父类公开的和默认的方法可以被子类继承使用, (私有化的private 不可以)
先执行父类的构造方法,在执行子类的构造方法 ,( 如果父类中没有无参构造方法,之类中也不能有),子类的构造方法要和父类的构造方法保持一致
类加载(必须创建对象)构造方法的时候,就会默认调用父类的无参构造方法
注: super表示父类
关于继承的概念
B继承了A, B叫A的子类, A叫B的父类,基类,超类
不能多继承,只能继承一个,但可以多重继承
无论父类还是子类都在堆中的同一个内存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0WEUEgxe-1679891771080)(D:\图片\image-20230314105352676.png)])
5. 重写与重载【🔺🔺🔺重点】
5.1 重写(Override)
重写的目的 : 让子类可以根据需要重新定义实现父类的方法(子类可以通过需要定义自己特定的行为)
1.必须在子类和父类之间的公开方法或者默认方法(除了static,private和final修饰的方法) 2.方法的名字相同,参数的类型,数量,顺序相同 【🔺🔺🔺重点】 4.返回值类型和修饰符与重写无关(java5之前返回值类型要一样) 5.访问权限不能比父类被重写的访问权限低 (比如父类的方法是public修饰的,子类中不能是private修饰的) 6.构造器不能被重写 7.@Override // 重写的严格限定,其下面的方法不是重写的方法会报错 8.父类类中被子类重写的方法,想在子类调用必须用super关键字
5.2 重载(Overload)
重载的目的 : 可以根据参数的个数,类型,顺序 匹配不同的方法,减少记方法名的繁琐
重载的规则:
1.重载必须在同一个类中 2.方法的名字相同 3.参数的个数,顺序,类型不同都构成重载 4.返回值类型和修饰符与重载无关【🔺🔺🔺】 5.被重载的方法可以改变方访问修饰符
5.3 重载重写的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | **必须**修改 | 一定**不能**修改 |
返回类型 | 可以修改 | 一定**不能**修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出异常或者更广的异常 |
访问 | 可以修改 | 一定不能做出严格的限制 |
6. Super关键字
当子类中要调用父类的方法(属性)或者被重写的方法时,要使用super关键字
super 代表当前类的父类
7. final关键字
可以用来修饰变量(包括类属性,对象属性,局部变量和形参),方法(包括类方法和对象方法)和类
被final修饰得类不能被继承;修饰的方法不能被重写
扩展【构造器】
定义:构造方法和构造函数
调用规则:
1. 子类不继承父类的构造器,只是调用(隐式或显式) 2. 如果父类的构造器有参数,子类在调用时,必须用**super**显式调用父类的构造器,并传递适当的参数 3.当父类没有构造器时,子类自动则调用父类的无参构造
8. 抽象类
格式:
abstract class 类名{ }
被 abstract 修饰的类
抽象方法 如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。 修饰关键词 abstract (返回值类型) 方法名();
- 如果一个类包含抽象方法,拿这个类必是抽象类
- 抽象类的子类必需重写抽象方法,或者声名自己为抽象方法
- 抽象类不能实例化对象,想要实例化对象,必须有子类重写实现该抽象方法(所以抽象类必须被继承才能被使用)
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
例子:
abstract class People{ String name; int age; public People(String name,int age){ this.name=name; this.age=age; } public abstract void sing(); } class People1 extends People{ public People1(String name, int age) { super(name, age);//调用父类构造方法 } @Override //重写标志 public void sing(){ System.out.println("唱歌"); } }
抽象方法:
1.一个类包含抽象方法,其必是抽象类 2.子类想要继承抽象的父类,必须重写抽象方法,否则就要声名自己为抽象类,就不能用来实例化对象
9. 接口【🔺🔺🔺重点】
语法格式:
interface 接口名称 [extends 其他的接口名] { // 声明变量 // 抽象方法 抽象方法1; 抽象方法2; 抽象方法3; }
接口的使用 (关键词implements)
class 类 implements 接口 { 重写接口中方法 }
使用关键字interface声明
一个接口中可以有多个方法,接口文件与java类文件相同
接口不能用于实例化对象
子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。
没有构造方法
接口中的方法必须都是抽象方法, 用public abstract修饰(java8之后可以是default修饰的非抽象方法)
不包含除static,final修饰的成员变量
接口需要被类实现(一个类可以继承多个接口进行实现)
interface Usb { //接口下面的都是抽象类 void mouse(); } interface Cable { void internate(); } interface Power_supply { void charge(); } class Computer implements Usb, Cable, Power_supply { int i = 0; public void mouse() { System.out.println("鼠标"); i++; } @Override public void internate() { System.out.println("联网"); i++; } @Override public void charge() { System.out.println("充电"); i++; } public void playgame(){ if (this.i==3){ System.out.println("登录成功"); }else { System.out.println("请检查设备"); } } } public class API { public static void main(String[] args) { Computer computer = new Computer(); computer.charge(); computer.mouse(); computer.internate(); computer.playgame(); } }
- 支持多继承
//文件名 Sports.java public interface Sports{ public void setName(String name); } //文件名 Football.java public interface Football{ public void setAge(int age); } //文件名 Hockey.java public interface Hockey exends Sports,Football{ public void set }
10. 多态 【🔺🔺🔺重要】
10.1 多态的基本概念
定义: 多态是同一个行为具有多个不同表现形式或形态的能力。
必要条件:
继承 (具有继承关系的两个类)
重写 (调用的只能是子类对父类的重写的方法)
父类引用指向子类对象
父类名 对象名 = new 子类名();
实现方式:
- 父类方法的重写
- 接口中抽象类的重写
图示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gUSc7itH-1679891771081)(D:\md文件\2DAC601E-70D8-4B3C-86CC-7E4972FC2466.jpg)]
例子:
class Shape { void draw() {} } class Circle extends Shape { void draw() {//构成重写 System.out.println("Circle.draw()"); } } class Square extends Shape { void draw() { System.out.println("Square.draw()"); } } class Triangle extends Shape { void draw() { System.out.println("Triangle.draw()"); } }
10.2 多态的转型【🔺🔺🔺重点】
多态的向上转型
格式:
父类 父类的引用 = new 子类();
- 向上转型是自动的将父类的对象赋值,父类的引用,指向子类的对象(调用的方法必须是重写的方法)
- 编译只编译引用类型,由于父类和子类中都含有同一个名字的方法,所以编译成功;但是JVM(java虚拟机)运行时,会调用new的类的对象的方法
- 只能调用子类对父类重写的方法
多态的向下转型
语法格式:
父类 父类的引用 = new 子类(); 子类 子类的引用 = (子类)父类的引用; //强制类型转换
- 可以调用子类有的方法
示例:
public class Test { public static void main(String[] args) { show(new Cat()); // 以 Cat 对象调用 show 方法 show(new Dog()); // 以 Dog 对象调用 show 方法 Animal a = new Cat(); // 向上转型 a.eat(); // 调用的是 Cat 的 eat Cat c = (Cat)a; // 向下转型 c.work(); // 调用的是 Cat 的 work } public static void show(Animal a) { a.eat(); // 类型判断 if (a instanceof Cat) { // 猫做的事情 Cat c = (Cat)a; c.work(); } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a; c.work(); } } } abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void work() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void work() { System.out.println("看家"); } }
10.3 instanceof关键字
语法格式:
对象的引用 instanceof 类
在java中instanceof是一个二元运算符,和> <类似,结果是false或者true
A instanceof B (B可以是A对象的类,也可以是其类的父类)
目的: 测试左边的额对象,是否是右边类的实例。(A是否是B的实例)
注: 属于什么类创建的对象,看创建时new的谁
11.static关键字
11.1 概念
static 静态的 (对象可以使用,但是和对象没有关系)
11.2 静态(static)在Java中的使用
static 修饰成员变量 (静态变量)
语法格式:
static 数据类型 变量名;
在main主函数中使用:
类名.静态变量 = 值;
注意事项:
- 使用static修饰的成员变量叫静态变量
- 代码静态变量可以被类中的所有实例共享
- 静态的方法不能调用非静态的
示例:public class StaticVar { public static String str1 = "Hello"; public static void main(String[] args) { String str2 = "World!"; // 直接访问str1 String accessVar1 = str1+str2; System.out.println("第 1 次访问静态变量,结果为:"+accessVar1); // 通过类名访问str1 String accessVar2 = StaticVar.str1+str2; System.out.println("第 2 次访问静态变量,结果为:"+accessVar2); // 通过对象svt1访问str1 StaticVar svt1 = new StaticVar(); svt1.str1 = svt1.str1+str2; String accessVar3 = svt1.str1; System.out.println("第3次访向静态变量,结果为:"+accessVar3); // 通过对象svt2访问str1 StaticVar svt2 = new StaticVar(); String accessVar4 = svt2.str1+str2; System.out.println("第 4 次访问静态变量,结果为:"+accessVar4); } }
静态方法 被static修饰的成员方法
- 静态方法不通过任何实例就可以调用,因此方法内不可以使用this关键字,且super也与对象的实例化有关,所以也不能使用
- 在实例方法(没有被static修饰的方法)中可以直接访问静态方法,静态变量
示例:
public class StaticMethod { public static int count = 1; // 定义静态变量count public int method1() { // 实例方法method1 count++; // 访问静态变量count并赋值 System.out.println("在静态方法 method1()中的 count="+count); // 打印count return count; } public static int method2() { // 静态方法method2 count += count; // 访问静态变量count并赋值 System.out.println("在静态方法 method2()中的 count="+count); // 打印count return count; } public static void PrintCount() { // 静态方法PrintCount count += 2; System.out.println("在静态方法 PrintCount()中的 count="+count); // 打印count } public static void main(String[] args) { StaticMethod sft = new StaticMethod(); // 通过实例对象调用实例方法 System.out.println("method1() 方法返回值 intro1="+sft.method1()); // 直接调用静态方法 System.out.println("method2() 方法返回值 intro1="+method2()); // 通过类名调用静态方法,打印 count StaticMethod.PrintCount(); } }
注: 在访问非静态方法时,需要通过实例对象来访问,而在访问静态方法时,可以直接访问,也可以通过类名来访问,还可以通过实例化对象来访问。
静态代码块 static{} 代码块
作用: 主要用于初始化类,为类的静态变量赋初始值,提升程序性能
格式:
static { 语句体; }
注意事项:
1.静态代码块不可以存在任何一个方法体中 2.静态代码快可以在类的任何地方,一个类中可以有多个静态代码快 3.一个方法中可以有多个静态代码快,在执行时按照顺序执行,每个只执行一次 4.静态代码块会先执行,(有时候会将只执行一次的初始化操作方法静态代码快中) 5.静态代码块和静态方法中不能直接访问实例方法和实例变量,需要通过实例对象(this)来访问
示例:
public class StaticCode { public static int count = 0; { count++; System.out.println("非静态代码块 count=" + count); } static { count++; System.out.println("静态代码块1 count=" + count); } static { count++; System.out.println("静态代码块2 count=" + count); } public static void main(String[] args) { System.out.println("*************** StaticCode1 执行 ***************"); StaticCode sct1 = new StaticCode(); System.out.println("*************** StaticCode2 执行 ***************"); StaticCode sct2 = new StaticCode(); } }
12.封装【复习】
定义:是指一种将抽象函式接口的实现细节包装,隐藏起来的方法
封装的优点
1.良好的封装可以减少耦合性 2.类的内部结构可以自由修改 3.可以对类的成员变量进行精确的控制 4.隐藏信息,实现细节
实现步骤:
- 修改属性的可见性,来限制对属性的访问,一般用private修饰
- 对每个属性值提供对外的公共访问方法,创建一对赋值取值的方法(setter,getter)
示例:
class People{ private String name; private int age; public People(){ } public People(String name,int age){ this.name=name; this.age=age; } }
注:采用 this 关键字是为了解决实例变量和局部变量之间发生的同名的冲突。
ticCode();
System.out.println("*************** StaticCode2 执行 ***************"); StaticCode sct2 = new StaticCode();
}
}
12.封装【复习】
定义:是指一种将抽象函式接口的实现细节包装,隐藏起来的方法
封装的优点
1.良好的封装可以减少耦合性 2.类的内部结构可以自由修改 3.可以对类的成员变量进行精确的控制 4.隐藏信息,实现细节
实现步骤:
- 修改属性的可见性,来限制对属性的访问,一般用private修饰
- 对每个属性值提供对外的公共访问方法,创建一对赋值取值的方法(setter,getter)
示例:
class People{ private String name; private int age; public People(){ } public People(String name,int age){ this.name=name; this.age=age; } }
注:采用 this 关键字是为了解决实例变量和局部变量之间发生的同名的冲突。