1. 继承 1.1 继承的概述 继承是面向对象三大特征之一。可以使得子类具有父类元素的属性和方法,还可以在子类中重新定义,追加属性和方法。
继承的格式:
格式:public class 子类名 extends 父类名
案例:public class ZI extends FU{}
FU类为父类(superclass),超类,基类
ZI类为子类(subclass),派生类,扩展类
继承中子类的特点:
子类可以有父类的内容
子类也可以有自己特有的内容
Java中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package extendsDemo;public class Fu { public void show () { System.out.println("Fu中方法被调用了" ); } } package extendsDemo;public class Zi extends Fu { public void method () { System.out.println("Zi中方法被调用" ); } } package extendsDemo;public class Demo { public static void main (String[] args) { Fu f = new Fu(); f.show(); Zi z= new Zi(); z.method(); z.show(); } } Fu中方法被调用了 Zi中方法被调用 Fu中方法被调用了
1.2 继承的好处的弊端 好处:
提高代码的复用性(多个类相同的成员可以放到同一个类中)
提高代码的维护性(如果方法的代码需要修改,修改一处即可)
弊端:
继承让类与类之间产生了关系,类的耦合性增强,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性。
什么时候使用继承?
假设法:有两个类A与B,如果他们之间满足A是B的一种,或者B是A的一种,就说明他们之间存在着继承关系,这个时候他们存在着继承关系,可以考虑使用继承,否则不能滥用继承
例如:苹果和水果,猫和动物(都可使用继承),猫和狗(不能使用继承)
1.3继承中变量的访问 在子类方法中访问一个变量的访问顺序:
子类局部范围找
子类成员范围找
父类成员范围找
如果都没有就报错(不考虑父类以上的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package extendsDemo;public class Fu { public int height = 185 ; public int age = 18 ; } package extendsDemo;public class Zi extends Fu { public int height = 183 ; public void method () { int height = 181 ; System.out.println(age); System.out.println(height); System.out.println(this .height); System.out.println(super .height); } } package extendsDemo;public class Demo { public static void main (String[] args) { Zi z= new Zi(); z.method(); } } 18 181 183 185
1.4 super关键字 super关键字和this关键字的用法相似之处
this:代表本类对象的引用(this关键字指向调用该方法的对象)
super:代表父类存储空间的标识(可以理解为父类引用对象)
关键字
访问成员变量
访问构造方法
访问成员方法
this
this.成员变量 访问本类成员变量
this(…..) 访问本类构造方法
this.成员方法(….) 访问本类成员方法
super
super.成员变量 访问父类成员变量
super(…..) 访问父类构造方法
super.成员方法(….) 访问fu类成员方法
注意事项 :
super能出现在实例方法和构造方法中。
super不能使用在静态方法中。
super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
super 不是引用,super也不保存内存地址,super也不指向任何对象;super 只是代表当前对象内部的那一块父类型的特征。
1.5 继承中构造方法的访问特点 子类中所有的构造方法默认都会访问父类中无参的构造方法:
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
每一个子类构造方法的第一条语句默认都是:super()
如果父类没有无参构造方法,只有带参构造方法,该怎么办?
通过使用super关键字去 显示的调用父类带参构造方法
在父类中自己提供一个无参构造方法
推荐:自己给出无参构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package extendsDemo;public class Fu { public Fu (int age) { System.out.println("fu中有参构造方法" ); } } package extendsDemo;public class Zi extends Fu { public Zi () { super (20 ); System.out.println("zi中无参构造方法" ); } public Zi (int age) { super (19 ); System.out.println("zi中有参构造方法" ); } } package extendsDemo;public class Demo { public static void main (String[] args) { Zi z= new Zi(); Zi z1 = new Zi(18 ); } } fu中有参构造方法 zi中无参构造方法 fu中有参构造方法 zi中有参构造方法
1.6 继承中成员方法的访问特点 通过子类对象访问一个方法:(就近原则)
子类成员范围找
父类成员范围找
如果没有就报错(不考虑父类以上)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package extendsDemo;public class Fu { public void show () { System.out.println("fu中的成员方法被调用" ); } } package extendsDemo;public class Zi extends Fu { public void method () { System.out.println("Zi中的成员方法被调用" ); } @Override public void show () { super .show(); System.out.println("zi中的成员方法被调用" ); } } package extendsDemo;public class Demo { public static void main (String[] args) { Zi z= new Zi(); z.show(); z.method(); } } fu中的成员方法被调用 zi中的成员方法被调用 Zi中的成员方法被调用
1.7 super内存图 点击观看视频详解
1.8 方法重写 方法重写概述:
当子类需要父类的功能,而主体子类有着自己特有的内容时,可以重写父类方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
什么条件满足的时候构成方法覆盖?
有继承关系的两个类
具有相同方法名、返回值类型、形式参数列表
访问权限不能更低
抛出异常不能更多
@Override
是一个注解
可以帮助我们检查重写的方法的 方法声明的正确性
方法重写的注意事项:
私有方法不能被重写(父类中private修饰 的不能在子类中 直接访问。可以通过间接的手段来访问。通过get方法来访问)
子类方法的访问权限不能低于父类(public > 默认 > 私有)
方法重写只是针对于方法,和属性无关。
构造方法不能被继承,所以构造方法也不能被重写。
方法重写只是针对于“实例方法”,“静态方法重写”没有意义。
方法重载和方法重写有什么区别?
方法重载发生在同一个类当中。
方法重写是发生在具有继承关系的父子类之间。
方法重载是一个类中,方法名相同,参数列表不同。
方法重写是具有继承关系的父子类,并且重写之后的方法 必须和之前的方法一致: 方法名一致、参数列表一致、返回值类型一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package iphone;public class Iphone { public void call (String name) { System.out.println("给" +name+"打电话" ); } } package iphone;public class NewIphone extends Iphone { @Override public void call (String name) { System.out.println("打开视频" ); super .call(name); } } package iphone;public class IphoneDemo { public static void main (String[] args) { Iphone p = new Iphone(); p.call("张三" ); System.out.println("-------------" ); NewIphone np = new NewIphone(); np.call("李四" ); } } 给张三打电话 ------------- 打开视频 给李四打电话
1.10 Java中继承的注意事项
Java中类只支持单继承,不支持多继承
Java支持多层继承(间接继承)
例如:class C extends B,class B extends A,
也就 是说,C 直接继承 B,
其实 C 还间接继承 A
1.11 案例 1. 老师和学生 :
需求:定义老师类和学生类,找到老师类和学生类的共性内容,抽取一个父类,用继承的方式改写代码,并进行测试
思路:
共性父类,定义人类(姓名, 年龄)
定义老师类,继承人类,给出自己的方法:教书()
定义老师类,继承人类,给出自己的方法:学习()
定义测试类,写代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 package studentAndTeacher;public class Teacher extends Person { public Teacher () { } public Teacher (String name, int age) { super (name, age); } public static void teach () { System.out.println("正在教书" ); } } package studentAndTeacher;public class Student extends Person { public Student () { } public Student (String name, int age) { super (name, age); } public static void stud () { System.out.println("正在学习" ); } } package studentAndTeacher;public 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 static void dos (String ds) { System.out.println(ds); } } package studentAndTeacher;public class Demo { public static void main (String[] args) { Student sc = new Student("张三" ,18 ); System.out.println(sc.getAge()+", " +sc.getName()); sc.stud(); sc.dos("学习" ); Teacher cc = new Teacher("李四" ,25 ); System.out.println(cc.getAge()+", " +cc.getName()); cc.teach(); cc.dos("教书" ); } } 18 , 张三正在学习 学习 25 , 李四正在教书 教书
2.猫和狗
需求: 采用继承的思想实现猫和狗的案例,并在测试类中进行测试
共性:
成员变量:姓名,年龄;构造方法:无参,带参;成员方法:get/set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 package catAndDog;public class Cat extends Animal { public Cat () { } public Cat (String name, int age) { super (name, age); } public static void show () { System.out.println("抓老鼠" ); } } public class Dog extends Animal { public Dog () { } public Dog (String name, int age) { super (name, age); } public static void method () { System.out.println("看家" ); } } package catAndDog;public 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 static void fn (String dos) { System.out.println(dos); } } package catAndDog;public class Demo { public static void main (String[] args) { Dog an = new Dog("ww" ,2 ); System.out.println(an.getName()+", " +an.getAge()); an.method(); an.fn("看门" ); Cat ca = new Cat("mm" ,1 ); System.out.println(ca.getName()+", " +ca.getAge()); ca.show(); ca.fn("抓小鸡" ); } } ww, 2 看家 看门 mm, 1 抓老鼠 抓小鸡
2. 修饰符 2.1包的概述和使用 其实就是文件夹 作用: 对类进行分类管理包的定义格式 1. 格式:package包名; (多级包用分开) 2. 范例:package com.itheima; 带包的)ava类编译和执行
手动建包: 1.按照以前的格式编译java文件 javac HelloWorld.java 2.手动创建包 在E盘建立文件夹com,然后在com下建立文件夹theima 3.把class文件放到包的最里面 把HelloWorld.class文件放到com下的Jitheimai这个文件夹下 4.带包执行 java com.itheima.HelloWorld 自动建包:
javac-d,HelloWorld.java java com.itheima.HelloWorld
2.2导包的概述和使用 使用不同包下的类时,使用的时候要写类的全路径,写起来太麻烦了 为了简化带包的操作,Jva就提供了导包的功能导包的格式 : 1. 格试:import包名: 2. 范例:import cn.itcast..Teacher
为了简化带包的操作,Jva就提供了导包的功能
导包的格式
格试:import包名:
范例:importcn.itcast.Teacher
2.3 修饰符权限
修饰符
同一个类中
同一个包中子类无关类
不同包的子类
不同包的无关类
private
yes
no
no
no
默认
yes
yes
no
no
protected
yes
yes
yes
no
public
yes
yes
yes
yes
2.4 final final关键字是最终的意思,可以修饰成员方法,成员变量,类
final修饰的特点:
修饰方法:表明该方法是最终的方法,不能被重写
修饰变量:表明该变量是常量,不能再次被赋值
修饰类:表明该类是最终类,不能被继承
final修饰局部变量
变量是基本类型:final修饰指的是基本类型的数据值不能发生改变
变量是引用类型:final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以改变的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package finalDemo;public class Student { public int age = 18 ; } package finalDemo;import org.w3c.dom.ls.LSOutput;public class FinalDemo { public static void main (String[] args) { final int age = 20 ; System.out.println(age); final Student s = new Student(); s.age = 20 ; System.out.println(s.age); } }
2.5 static static关键字是静态的意思,可以修饰成员变量,成员方法
static修饰的特点:
被类的所有对象共享;这是判断是否使用静态关键字的条件
可以通过类名调用;也可以通过对象名调用;推荐使用类名调用
2.6 static访问特点 非静态成员方法:
能访问静态的成员变量
能访问非静态的成员变量
能访问静态的成员方法
能访问非静态的成员方法
静态成员方法:
总结:静态成员方法只能访问静态成员
3. 多态 3.1 多态的概述
同一个对象,在不同时刻表现出来的不同形态
多种形态,多种状态,编译和运行有两个不同的状态。
编译期叫做静态绑定。
运行期叫做动态绑定。
Animal a = new Cat(); //父类引用指向子类对象
// 编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move()方法
// 找到了,绑定,编译通过。但是运行的时候和底层堆内存当中的实际对象有关
// 真正执行的时候会自动调用“堆内存中真实对象”的相关方法。
多态在开发中的作用是: 降低程序的耦合度,提高程序的扩展力。
多态的前提和实现:
有继承/实现关系
有方法重写
有父类引用指向子类对象
3.2 多态中成员访问特点 成员变量: 编译看左边,执行看左边
成员方法: 编译看左边,执行看右边
为什么成员变量和成员方法不一样?
3.3 多态的好处和弊端
具体体现:定义方法的时候,使用父类型作为参数,将来使用的时候,使用具体的子类型参与操作
3.4 多态中的转型 向上转型: 子—>父 (upcasting) 又被称为自动类型转换:Animal a = new Cat();
向下转型: 父—>子 (downcasting) 又被称为强制类型转换:Cat c = (Cat)a; 需要添加强制类型转换符。
什么时候需要向下转型? 1.需要调用或者执行子类对象中特有的方法。 2.必须进行向下转型,才可以调用。向下转型有风险吗? 1.容易出现ClassCastException(类型转换异常)怎么避免这个风险? 1. instanceof运算符,可以在程序运行阶段动态的判断某个引用指向的对象是否为某一种类型。
不管是向上转型还是向下转型,首先他们之间必须有继承关系,这样编译器就不会报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package demo_01;public class Animal { public void eat () { System.out.println("吃东西" ); } } package demo_01;public class Cat extends Animal { @Override public void eat () { System.out.println("猫吃鱼" ); } public void show () { System.out.println("猫捉老鼠" ); } } package demo_01;public class AnimalDemo { public static void main (String[] args) { Animal a = new Cat(); a.eat(); Cat b = (Cat)a; b.eat(); b.show(); } }
3.5 猫和狗(多态版) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 package catAndDog;public 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 void eat () { System.out.println("吃东西" ); } } package catAndDog;public class Dog extends Animal { public Dog () { } public Dog (String name, int age) { super (name, age); } @Override public void eat () { System.out.println("饿狗扑食" ); } public void show () { System.out.println("小狗玩耍" ); } } package catAndDog;import demo_01.Cat;public class AnimalDemo { public static void main (String[] args) { Animal a = new Dog("小黄" , 6 ); a.eat(); System.out.println("--------------" ); Dog d = (Dog) a; d.eat(); d.show(); System.out.println("--------------" ); } } 饿狗扑食 -------------- 饿狗扑食 小狗玩耍 --------------
4. 抽象类 4.1 抽象类的概念 在Java中,一个没有方法体的方法应该定义为抽象方法,而类中的如果有抽象方法,该类必须定义为抽象类
1 2 3 4 5 6 7 package demo_01;public abstract class Animal { public abstract void eat () ; }
4.2 抽象类的特点
public abstract class 类名{}
public abstract void eat();
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能实例化
抽象类如何实例化呢?参照多态的形式,通过子类对象实例化,这叫抽象类多态
1.要么重写抽象类中的所有抽象方法
2.要么是抽象类
4.3 抽象类的成员特点
可以是变量
也可以是常量
有构造方法,但不能实例化
构造方法的作用是什么呢?用于子类访问父类数据的初始化
可以有抽象方法:限定子类必须完成某些动作
也可以有非抽象方法:提高代码复用性
4.4 猫和狗(抽象类版) 需求:采用抽象类的思想实现猫和狗的案例,并在测试类中进行测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 package catAndDog;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 catAndDog;public class Cat extends Animal { public Cat () { } public Cat (String name, int age) { super (name, age); } @Override public void eat () { System.out.println("小猫吃鱼" ); } public void show () { System.out.println("66666666" ); } } package catAndDog;public class AnimalDemo { public static void main (String[] args) { Animal a = new Cat(); a.setName("大菊" ); a.setAge(2 ); System.out.println(a.getName() + ", " + a.getAge()); a.eat(); System.out.println("--------------" ); a = new Cat("小黄" , 3 ); System.out.println(a.getName() + ", " + a.getAge()); a.eat(); System.out.println("--------------" ); Cat b = (Cat) a; b.show(); } } 大菊, 2 小猫吃鱼 -------------- 小黄, 3 小猫吃鱼 -------------- 66666666
5. 接口 5.1 接口概述
5.2 接口的特点
public interface 接口名{}
public class 类名 implements 接口名{}
1.接口如何实例化? 参照多态的方式,通过实现子类对象实例化,这叫接口实例化
2.多态的形式:具体类多态, 抽象类多态 , 接口多态
1.要么重写接口中的所有抽象方法
2.要么是抽象类
5.3 接口成员的特点
只能是常量
默认修饰符:public static final(可省略)
1. 接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在的
2. 一个类如果没有父类,默认继承Object
成员方法
只能是抽象方法
默认修饰符:public abstract
5.4 猫和狗(接口版) 需求:对猫和狗进行训练,他们就可以调高,这里加入了调高功能,请采用抽象类和接口来实现猫和狗案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 //1.定义接口 package catAndDog; public interface Jumpping { public abstract void jump(); } //2.定义动物类 package catAndDog; public abstract class Animal { private String namne; private int age; public Animal() { } public Animal(String namne, int age) { this.namne = namne; this.age = age; } public String getNamne() { return namne; } public void setNamne(String namne) { this.namne = namne; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void eat(); } //3.定义猫类 package catAndDog; public class Cat extends Animal implements Jumpping{ public Cat() { } public Cat(String namne, int age) { super(namne, age); } @Override public void eat() { System.out.println("小猫吃鱼"); } @Override public void jump() { System.out.println("小猫跳高"); } } //4.测试类 package catAndDog; public class AnimalDemo { public static void main(String[] args) { Jumpping j = new Cat(); j.jump(); System.out.println("--------------"); Animal a = new Cat("加菲猫", 3); System.out.println(a.getNamne() + ", " + a.getAge()); a.eat(); // a.jump(); 报错 System.out.println("--------------"); a = new Cat("大菊", 2); System.out.println(a.getNamne() + ", " + a.getAge()); a.eat(); } } //运行结果 小猫跳高 -------------- 加菲猫, 3 小猫吃鱼 -------------- 大菊, 2 小猫吃鱼
5.5 类和接口的关系
继承关系,只能单继承,但是可以多层继承
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
继承关系,可以单继承,也可以多继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package Demo_02;public interface Inter1 {} package Demo_02;public interface Inter2 {} package Demo_02;public interface Inter3 extends Inter1 , Inter2 { } package Demo_02;public class Demo extends Object implements Inter1 ,Inter2 { }
5.6 抽象类和接口的区别
抽象类:变量,常量;有构造方法;有抽象方法,也有非抽象方法
接口:常量,抽象方法
类与类:继承,单继承
类与接口:实现,可以单实现,也可以多实现
接口与接口:继承,单继承,多继承
抽象类:对类抽象,包括属性和行为
接口:对行为抽象,主要是行为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package Demo_02;public interface Inter1 { void jump () ; } package Demo_02;public abstract class Cat { public abstract void eat () ; } package Demo_02;public class Demo extends Cat implements Inter1 { @Override public void jump () { } @Override public void eat () { } }
5.7 运动员和教练(案例)
需求:我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。为了出国交流,跟乒乓球相关的人员都需要学习英语。请用所有知识分析,这个案例中有哪些具体类,哪些抽象类,哪些接口,并用代码实现 思路:
①定义说英语接口 成员方法:说英语(): ②定义抽象人类 成员变量:姓名,年龄;构造方法:无参,带参;成员方法:get/st方法,吃饭(); ③定义抽象教练类,继承人类 构造方法:无参,带参;成员方法:教(); ④定义抽象运动员类,继承人类 构造方法:无参,带参;成员方法:学习(): ⑤定义具体篮球教练类,继承教练类 构造方法:无参,带参;成员方法:重写吃饭(){……},重写教(){……} ⑥定义具体乒乓球教练类,继教练类,实现说英语接口 构造方法:无参,带参;成员方法:重写吃饭(){……},重写教(){……},重写说英语(){……} ⑦定义具体篮球运动员类,继承运动员类 构造方法:无参,带参;成员方法:重写吃饭(){……},重写学习(){……} ⑧定义具体乒乓球运动员类,继承运动员类,实现说英语接口 构造方法:无参,带参;成员方法:重写吃饭(){……},重写学习(){……},重写说英语(){……} ⑨定义测试类,写代码测试
6. 形参和返回值 6.1 类名作为形参和返回值
方法的形参是类名,其实需要的是该类的对象
方法的返回值类名,其实返回的是该类的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package demo_03;public class Cat { public void eat () { System.out.println("猫吃鱼" ); } } package demo_03;public class CatOperator { public void usecat (Cat c) { c.eat(); } public Cat method () { Cat b = new Cat(); return b; } } package demo_03;public class CatDemo { public static void main (String[] args) { CatOperator op = new CatOperator(); Cat c = new Cat(); op.usecat(c); Cat a = op.method(); a.eat(); } } 猫吃鱼 猫吃鱼
6.2 抽象类名作为形参和返回值
方法的形参是抽象类名,其实需要的是该抽象类的子类对象
方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package Demo_04;public abstract class Animal { public abstract void eat () ; } package Demo_04;public class AnimalOperator { public void show (Animal a) { a.eat(); } public Animal method () { Animal b= new Cat(); return b; } } package Demo_04;public class Cat extends Animal { @Override public void eat () { System.out.println("猫吃鱼" ); } } package Demo_04;public class AnimalDemo { public static void main (String[] args) { AnimalOperator s = new AnimalOperator(); Animal c = new Cat(); s.show(c); Animal m = s.method(); m.eat(); } } 猫吃鱼 猫吃鱼
6.3 接口名作为形参和返回值
方法的形参是接口名,其实需要的是该接口的实现类对象
方法的返回值是接口名,其实返回的是该接口的实现类对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package Demo_05;public interface Jumpping { void jump () ; } package Demo_05;import Demo_01.Jump;public class JumppingOperator { public void show (Jumpping a) { a.jump(); } public Jumpping method () { Jumpping b= new Cat(); return b; } } package Demo_05;public class Cat implements Jumpping { @Override public void jump () { System.out.println("猫跳高" ); } } package Demo_05;public class JumppingDemo { public static void main (String[] args) { JumppingOperator j = new JumppingOperator(); Jumpping s = new Cat(); j.show(s); Jumpping m = j.method(); m.jump(); } } 猫跳高 猫跳高
7. 内部类 7.1 内部类概述
内部类可以访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package demo_01;public class Outer { private int age = 18 ; public class Inner { public void show () { System.out.println(age); } } public void method () { Inner a = new Inner(); a.show(); } } package demo_01;public class OuterDemo { public static void main (String[] args) { Outer o = new Outer(); o.method(); } } 18
7.2 成员内部类 按照内部类在类中定义的位置不同,可以分为如下两种形式:
在类的成员位置:成员内部类(在成员变量定义的类)
在类的局部位置:局部内部类(在方法中定义的类)
成员内部类,外界如何使用呢?
格式:外部类名.内部类名 对象明 = 外部类对象.内部类对象
范例:Outer.Inner oi = new Outer().new Inner();
局部内部类:
局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用,该类可以直接访问外部类的成员,也可以访问的方法内的局部变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package demo_01;public class Outer { private int age = 18 ; public class Inner { public void show () { System.out.println(age); } } public void method () { int age2 = 20 ; class Inner { public void show () { System.out.println(age); System.out.println(age2); } } Inner i = new Inner(); i.show(); } } package demo_01;public class OuterDemo { public static void main (String[] args) { Outer.Inner oi = new Outer().new Inner () ; oi.show(); System.out.println("-----------" ); Outer o = new Outer(); o.method(); } } 18 ----------- 18 20
7.3 匿名内部类 前提:存在一个类或者接口,在这里类可以是具体的类也可以是抽象的类
new 类名或者接口名(){
重写方法;
};
new Inter(){
public void show(){
}
};
本质:是一个继承了该类或者实现了该接口的子类匿名对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package demo_02;public interface Inter { void show () ; } package demo_02;public class Outer { public void method () { Inter i = new Inter(){ @Override public void show () { System.out.println("匿名内部类" ); } }; i.show(); i.show(); } } package demo_02;public class OuterDemo { public static void main (String[] args) { Outer o = new Outer(); o.method(); } } 匿名内部类 匿名内部类
7.4 匿名内部类在开发中的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 package Demo_03;public interface Jumpping { void jump () ; } package Demo_03;public class JumppingOpertor { public void method (Jumpping j) { j.jump(); } } package Demo_03;public class Cat implements Jumpping { @Override public void jump () { System.out.println("小猫跳高了" ); } } package Demo_03;public class JumppingDemo { public static void main (String[] args) { JumppingOpertor s = new JumppingOpertor(); Jumpping c = new Cat(); s.method(c); System.out.println("-----------" ); s.method(new Jumpping() { @Override public void jump () { System.out.println("小狗跳高" ); } }); } } 小猫跳高了 ----------- 小狗跳高
冒泡排序 排序:将一组数据按照固定的规则进行排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package test;public class MaoPaoDemo { public static void main (String[] args) { int [] arr = {52 , 66 , 42 , 88 , 33 }; String c = arrayToString(arr); System.out.println("排序前:" +c); for (int x = 0 ; x < arr.length - 1 ; x++) { for (int i = 0 ; i < arr.length - 1 - x; i++) { if (arr[i] > arr[i + 1 ]) { int temp = arr[i]; arr[i] = arr[i + 1 ]; arr[i + 1 ] = temp; } } } System.out.println("排序后:" +arrayToString(arr)); } public static String arrayToString (int [] arr) { StringBuilder s = new StringBuilder(); s.append("[" ); for (int i = 0 ; i < arr.length; i++) { if (i == arr.length - 1 ) { s.append(arr[i]); } else { s.append(arr[i]).append("," ); } } s.append("]" ); return s.toString(); } } 排序前:[52 ,66 ,42 ,88 ,33 ] 排序后:[33 ,42 ,52 ,66 ,88 ]