做网站用什么后缀格式做好,网站建设主题与建设目标,淘宝网页版登录入口电脑版,定制研发服务第一章 抽象类
1.1 概述
1.1.1 抽象类引入
父类中的方法#xff0c;被它的子类们重写#xff0c;子类各自的实现都不尽相同。那么父类的方法声明和方法主体#xff0c;只有声明还有意义#xff0c;而方法主体则没有存在的意义了(因为子类对象会调用自己重写的方法)。…第一章 抽象类
1.1 概述
1.1.1 抽象类引入
父类中的方法被它的子类们重写子类各自的实现都不尽相同。那么父类的方法声明和方法主体只有声明还有意义而方法主体则没有存在的意义了(因为子类对象会调用自己重写的方法)。换句话说父类可能知道子类应该有哪个功能但是功能具体怎么实现父类是不清楚的由子类自己决定父类只需要提供一个没有方法体的定义即可具体实现交给子类自己去实现。我们把没有方法体的方法称为抽象方法。Java语法规定包含抽象方法的类就是抽象类。
抽象方法 没有方法体的方法。抽象类包含抽象方法的类。
1.2 abstract使用格式
abstract是抽象的意思用于修饰方法方法和类修饰的方法是抽象方法修饰的类是抽象类。
1.2.1 抽象方法
使用abstract 关键字修饰方法该方法就成了抽象方法抽象方法只包含一个方法名而没有方法体。
定义格式
修饰符 abstract 返回值类型 方法名 (参数列表)代码举例
public abstract void run()1.2.2 抽象类
如果一个类包含抽象方法那么该类必须是抽象类。注意抽象类不一定有抽象方法但是有抽象方法的类必须定义成抽象类。
抽象类不能实例化。 可以有构造方法创建子类对象时给属性赋值。 抽象类的子类要么重写抽象类中的所有抽象方法要么是抽象类
定义格式
abstract class 类名字 { }代码举例
public abstract class Animal {public abstract void run()
}1.2.3 抽象类的使用
要求继承抽象类的子类必须重写父类所有的抽象方法。否则该子类也必须声明为抽象类。
代码举例
// 父类,抽象类
abstract class Employee {private String id;private String name;private double salary;public Employee() {}public Employee(String id, String name, double salary) {this.id id;this.name name;this.salary salary;}// 抽象方法// 抽象方法必须要放在抽象类中abstract public void work();
}// 定义一个子类继承抽象类
class Manager extends Employee {public Manager() {}public Manager(String id, String name, double salary) {super(id, name, salary);}// 2.重写父类的抽象方法Overridepublic void work() {System.out.println(管理其他人);}
}// 定义一个子类继承抽象类
class Cook extends Employee {public Cook() {}public Cook(String id, String name, double salary) {super(id, name, salary);}Overridepublic void work() {System.out.println(厨师炒菜多加点盐...);}
}// 测试类
public class Demo10 {public static void main(String[] args) {// 创建抽象类,抽象类不能创建对象// 假设抽象类让我们创建对象,里面的抽象方法没有方法体,无法执行.所以不让我们创建对象
// Employee e new Employee();
// e.work();// 3.创建子类Manager m new Manager();m.work();Cook c new Cook(ap002, 库克, 1);c.work();}
}此时的方法重写是子类对父类抽象方法的完成实现我们将这种方法重写的操作也叫做实现方法。
1.3 抽象类的特征
抽象类的特征总结起来可以说是 有得有失
有得抽象类得到了拥有抽象方法的能力。
有失抽象类失去了创建对象的能力。
其他成员构造方法实例方法静态方法等抽象类都是具备的。
1.4 抽象类的细节 抽象类不能创建对象如果创建编译无法通过而报错。只能创建其非抽象子类的对象。 理解假设创建了抽象类的对象调用抽象的方法而抽象方法没有具体的方法体没有意义。 抽象类中可以有构造方法是供子类创建对象时初始化父类成员使用的。 理解子类的构造方法中有默认的super()需要访问父类构造方法。 抽象类中不一定包含抽象方法但是有抽象方法的类必定是抽象类。 理解未包含抽象方法的抽象类目的就是不想让调用者创建该类对象通常用于某些特殊的类结构设计。 抽象类的子类必须重写抽象父类中所有的抽象方法否则子类也必须定义成抽象类编译无法通过而报错。 理解假设不重写所有抽象方法则类中可能包含抽象方法。那么创建对象后调用抽象的方法没有意义。 抽象类存在的意义是为了被子类继承。 理解抽象类中已经实现的是模板中确定的成员抽象类不确定如何实现的定义成抽象方法交给具体的子类去实现。
1.5 抽象类存在的意义
抽象类存在的意义是为了被子类继承否则抽象类将毫无意义。抽象类可以强制让子类一定要按照规定的格式进行重写。
第二章 接口
2.1 概述
接口是更加彻底的抽象JDK7之前包括JDK7接口中全部是抽象方法。接口同样是不能创建对象的。
2.2 定义格式
//接口的定义格式
interface 接口名称{// 抽象方法
}// 接口的声明interface
// 接口名称首字母大写满足“驼峰模式”2.3 接口成分的特点
在JDK7包括JDK7之前接口中的只有包含抽象方法和常量
2.3.1.抽象方法
注意接口中的抽象方法默认会自动加上public abstract修饰程序员无需自己手写 按照规范以后接口中的抽象方法建议不要写上public abstract。因为没有必要啊默认会加上。
2.3.2 常量
在接口中定义的成员变量默认会加上 public static final修饰。也就是说在接口中定义的成员变量实际上是一个常量。这里是使用public static final修饰后变量值就不可被修改并且是静态化的变量可以直接用接口名访问所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写多个单词用下划线连接。
2.3.3 案例演示
public interface InterF {// 抽象方法// public abstract void run();void run();// public abstract String getName();String getName();// public abstract int add(int a , int b);int add(int a , int b);// 它的最终写法是// public static final int AGE 12 ;int AGE 12; //常量String NAME 程序员;}2.4 基本的实现
2.4.1 实现接口的概述
类与接口的关系为实现关系即类实现接口该类可以称为接口的实现类也可以称为接口的子类。实现的动作类似继承格式相仿只是关键字不同实现使用 implements关键字。
2.4.2 实现接口的格式
/**接口的实现在Java中接口是被实现的实现接口的类称为实现类。实现类的格式:*/
class 类名 implements 接口1,接口2,接口3...{}从上面格式可以看出接口是可以被多实现的。大家可以想一想为什么呢
2.4.3 类实现接口的要求和意义
必须重写实现的全部接口中所有抽象方法。如果一个类实现了接口但是没有重写完全部接口的全部抽象方法这个类也必须定义成抽象类。意义接口体现的是一种规范接口对实现类是一种强制性的约束要么全部完成接口申明的功能要么自己也定义成抽象类。这正是一种强制性的规范。
2.4.4 类与接口基本实现案例
假如我们定义一个运动员的接口规范代码如下
/**接口接口体现的是规范。* */
public interface SportMan {void run(); // 抽象方法跑步。void law(); // 抽象方法遵守法律。String compittion(String project); // 抽象方法比赛。
}接下来定义一个乒乓球运动员类实现接口实现接口的实现类代码如下
package com.itheima._03接口的实现;
/*** 接口的实现* 在Java中接口是被实现的实现接口的类称为实现类。* 实现类的格式:* class 类名 implements 接口1,接口2,接口3...{*** }* */
public class PingPongMan implements SportMan {Overridepublic void run() {System.out.println(乒乓球运动员稍微跑一下);}Overridepublic void law() {System.out.println(乒乓球运动员守法);}Overridepublic String compittion(String project) {return 参加project得金牌;}
}测试代码
public class TestMain {public static void main(String[] args) {// 创建实现类对象。PingPongMan zjk new PingPongMan();zjk.run();zjk.law();System.out.println(zjk.compittion(全球乒乓球比赛));}
}2.4.5 类与接口的多实现案例
类与接口之间的关系是多实现的一个类可以同时实现多个接口。
首先我们先定义两个接口代码如下
/** 法律规范接口*/
public interface Law {void rule();
}/** 这一个运动员的规范接口*/
public interface SportMan {void run();
}
然后定义一个实现类
/*** Java中接口是可以被多实现的* 一个类可以实现多个接口: Law, SportMan** */
public class JumpMan implements Law ,SportMan {Overridepublic void rule() {System.out.println(尊长守法);}Overridepublic void run() {System.out.println(训练跑步);}
}从上面可以看出类与接口之间是可以多实现的我们可以理解成实现多个规范这是合理的。
2.5 接口与接口的多继承
Java中接口与接口之间是可以多继承的也就是一个接口可以同时继承多个接口。大家一定要注意
类与接口是实现关系
接口与接口是继承关系
接口继承接口就是把其他接口的抽象方法与本接口进行了合并。
案例演示
public interface Abc {void go();void test();
}/** 法律规范接口*/
public interface Law {void rule();void test();
}** 总结* 接口与类之间是多实现的。* 接口与接口之间是多继承的。* */
public interface SportMan extends Law , Abc {void run();
}2.6扩展接口的细节
当两个接口中存在相同抽象方法的时候该怎么办 只要重写一次即可。此时重写的方法既表示重写1接口的也表示重写2接口的。 实现类能不能继承A类的时候同时实现其他接口呢 继承的父类就好比是亲爸爸一样 实现的接口就好比是干爹一样 可以继承一个类的同时再实现多个接口只不过要把接口里面所有的抽象方法全部实现。 实现类能不能继承一个抽象类的时候同时实现其他接口呢 实现类可以继承一个抽象类的同时再实现其他多个接口只不过要把里面所有的抽象方法全部重写。 实现类Zi实现了一个接口还继承了一个Fu类。假设在接口中有一个方法父类中也有一个相同的方法。子类如何操作呢 处理办法一如果父类中的方法体能满足当前业务的需求在子类中可以不用重写。 处理办法二如果父类中的方法体不能满足当前业务的需求需要在子类中重写。 如果一个接口中有10个抽象方法但是我在实现类中只需要用其中一个该怎么办? 可以在接口跟实现类中间新建一个中间类适配器类 让这个适配器类去实现接口对接口里面的所有的方法做空重写。 让子类继承这个适配器类想要用到哪个方法就重写哪个方法。 因为中间类没有什么实际的意义所以一般会把中间类定义为抽象的不让外界创建对象 JDK8以后接口中新增的方法 允许在接口中定义默认方法需要使用default关键字 作用解决接口升级问题
接口中默认方法的定义格式 格式public default 返回值类型 方法名参数列表{} 范例public default void show(){}
接口中默认方法的注意事项 默认方法不是抽象方法所以不强制重写。但是如果被重写重写的时候去掉default关键字 public可以省略default不能省略 如果实现了多个接口多个接口存在相同名字的默认方法子类就必须对该方法进行重写。
允许在接口中定义静态方法需要使用static关键字
接口中静态方法的定义格式 格式public static 返回值类型 方法名参数列表{} 范例public static void show(){}
接口中静态方法的注意事项 静态方法只能通过接口名调用不能通过实现类或者对象名调用 public可以省略static不能省略
JDK9新增的方法 接口中私有方法的定义格式 格式private 返回值类型 方法名参数列表{} 范例private void show(){}
格式private static 返回值类型 方法名参数列表{} 范例private static void show(){}
总结 JDK7以前接口中只能定义抽象方法 JDK8接口中可以定义有方法体的方法。默认静态 JDK9接口中可以定义私有方法。 私有方法分为普通私有方法静态私有方法
接口代表规则是行为的抽象。想要让哪个类拥有一个行为就让这个类实现对应的接口就可以了。 当一个方法的参数是接口时可以传递接口所有实现类的对象这种方式称之为接口多态。
适配器设计模式 设计模式是一套被反复使用多数人知晓的经过分类编目的代码设计经验的总结。 使用设计模式是为了可重用代码让代码更容易被他人理解保证代码可靠性程序的重用性。 作用解决接口与接口实现类的矛盾问题。
第三章 内部类
3.1 概述
3.1.1 什么是内部类
将一个类A定义在另一个类B里面里面的那个类A就称为内部类B则称为外部类。可以把内部类理解成寄生外部类理解成宿主。
3.1.2 什么时候使用内部类
一个事物内部还有一个独立的事物内部的事物脱离外部的事物无法独立使用
人里面有一颗心脏。汽车内部有一个发动机。为了实现更好的封装性。
3.2 内部类的分类
按定义的位置来分
成员内部内类定义在了成员位置 (类中方法外称为成员位置无static修饰的内部类)静态内部类类定义在了成员位置 (类中方法外称为成员位置有static修饰的内部类)局部内部类类定义在方法内匿名内部类没有名字的内部类可以在方法中也可以在类中方法外。
3.3 成员内部类
成员内部类特点
无static修饰的内部类属于外部类对象的。宿主外部类对象。
内部类的使用格式 外部类.内部类。 // 访问内部类的类型都是用 外部类.内部类获取成员内部类对象的两种方式
方式一外部直接创建成员内部类的对象
外部类.内部类 变量 new 外部类.new 内部类;方式二在外部类中定义一个方法提供内部类的对象
案例演示
方式一
public class Test {public static void main(String[] args) {// 宿主外部类对象。// Outer out new Outer();// 创建内部类对象。Outer.Inner oi new Outer().new Inner();oi.method();}
}class Outer {// 成员内部类属于外部类对象的。// 拓展成员内部类不能定义静态成员。public class Inner{// 这里面的东西与类是完全一样的。public void method(){System.out.println(内部类中的方法被调用了);}}
}方式二
public class Outer {String name;private class Inner{static int a 10;}public Inner getInstance(){return new Inner();}
}public class Test {public static void main(String[] args) {Outer o new Outer();System.out.println(o.getInstance());}
}3.4 成员内部类的细节
编写成员内部类的注意点
成员内部类可以被一些修饰符所修饰比如 private默认protectedpublicstatic等在成员内部类里面JDK16之前不能定义静态变量JDK16开始才可以定义静态变量。创建内部类对象时对象中有一个隐含的Outer.this记录外部类对象的地址值。请参见3.6节的内存图
详解
内部类被private修饰外界无法直接获取内部类的对象只能通过3.3节中的方式二获取内部类的对象
被其他权限修饰符修饰的内部类一般用3.3节中的方式一直接获取内部类的对象
内部类被static修饰是成员内部类中的特殊情况叫做静态内部类下面单独学习。
内部类如果想要访问外部类的成员变量外部类的变量必须用final修饰JDK8以前必须手动写finalJDK8之后不需要手动写JDK默认加上。
3.5 成员内部类面试题
请在?地方向上相应代码,以达到输出的内容
注意内部类访问外部类对象的格式是外部类名.this
public class Test {public static void main(String[] args) {Outer.inner oi new Outer().new inner();oi.method();}
}class Outer { // 外部类private int a 30;// 在成员位置定义一个类class inner {private int a 20;public void method() {int a 10;System.out.println(???); // 10 答案aSystem.out.println(???); // 20 答案this.aSystem.out.println(???); // 30 答案Outer.this.a}}
}3.6 成员内部类内存图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NgVlKsQS-1686986549627)(img\内部类内存图.png)]
3.7 静态内部类
静态内部类特点
静态内部类是一种特殊的成员内部类。
有static修饰属于外部类本身的。总结静态内部类与其他类的用法完全一样。只是访问的时候需要加上外部类.内部类。拓展1:静态内部类可以直接访问外部类的静态成员。拓展2:静态内部类不可以直接访问外部类的非静态成员如果要访问需要创建外部类的对象。拓展3:静态内部类中没有银行的Outer.this。
内部类的使用格式
外部类.内部类。静态内部类对象的创建格式
外部类.内部类 变量 new 外部类.内部类构造器;调用方法的格式
调用非静态方法的格式先创建对象用对象调用调用静态方法的格式外部类名.内部类名.方法名();
案例演示
// 外部类Outer01
class Outer01{private static String sc_name 黑马程序;// 内部类: Inner01public static class Inner01{// 这里面的东西与类是完全一样的。private String name;public Inner01(String name) {this.name name;}public void showName(){System.out.println(this.name);// 拓展:静态内部类可以直接访问外部类的静态成员。System.out.println(sc_name);}}
}public class InnerClassDemo01 {public static void main(String[] args) {// 创建静态内部类对象。// 外部类.内部类 变量 new 外部类.内部类构造器;Outer01.Inner01 in new Outer01.Inner01(张三);in.showName();}
}3.8 局部内部类
局部内部类 定义在方法中的类。
定义格式:
class 外部类名 {数据类型 变量名;修饰符 返回值类型 方法名(参数列表) {// …class 内部类 {// 成员变量// 成员方法}}
}3.9 匿名内部类【重点】
3.9.1 概述
匿名内部类 是内部类的简化写法。他是一个隐含了名字的内部类。开发中最常用到的内部类就是匿名内部类了。
3.9.2 格式
new 类名或者接口名() {重写方法;
};包含了 继承或者实现关系 方法重写 创建对象
所以从语法上来讲这个整体其实是匿名内部类对象
3.9.2 什么时候用到匿名内部类
实际上如果我们希望定义一个只要使用一次的类就可考虑使用匿名内部类。匿名内部类的本质作用
是为了简化代码。
之前我们使用接口时似乎得做如下几步操作
定义子类重写接口中的方法创建子类对象调用重写后的方法
interface Swim {public abstract void swimming();
}// 1. 定义接口的实现类
class Student implements Swim {// 2. 重写抽象方法Overridepublic void swimming() {System.out.println(狗刨式...);}
}public class Test {public static void main(String[] args) {// 3. 创建实现类对象Student s new Student();// 4. 调用方法s.swimming();}
}我们的目的最终只是为了调用方法那么能不能简化一下把以上四步合成一步呢匿名内部类就是做这样的快捷方式。
3.9.3 匿名内部类前提和格式
匿名内部类必须继承一个父类或者实现一个父接口。
匿名内部类格式
new 父类名或者接口名(){// 方法重写Override public void method() {// 执行语句}
};3.9.4 使用方式
以接口为例匿名内部类的使用代码如下
interface Swim {public abstract void swimming();
}public class Demo07 {public static void main(String[] args) {// 使用匿名内部类new Swim() {Overridepublic void swimming() {System.out.println(自由泳...);}}.swimming();// 接口 变量 new 实现类(); // 多态,走子类的重写方法Swim s2 new Swim() {Overridepublic void swimming() {System.out.println(蛙泳...);}};s2.swimming();s2.swimming();}
}3.9.5 匿名内部类的特点
定义一个没有名字的内部类这个类实现了父类或者父类接口匿名内部类会创建这个没有名字的类的对象
3.9.6 匿名内部类的使用场景
通常在方法的形式参数是接口或者抽象类时也可以将匿名内部类作为参数传递。代码如下
interface Swim {public abstract void swimming();
}public class Demo07 {public static void main(String[] args) {// 普通方式传入对象// 创建实现类对象Student s new Student();goSwimming(s);// 匿名内部类使用场景:作为方法参数传递Swim s3 new Swim() {Overridepublic void swimming() {System.out.println(蝶泳...);}};// 传入匿名内部类goSwimming(s3);// 完美方案: 一步到位goSwimming(new Swim() {public void swimming() {System.out.println(大学生, 蛙泳...);}});goSwimming(new Swim() {public void swimming() {System.out.println(小学生, 自由泳...);}});}// 定义一个方法,模拟请一些人去游泳public static void goSwimming(Swim s) {s.swimming();}
}