飞机大战分析:
对象提取类:小敌机/大敌机/自己的飞机/子弹/小蜜蜂
小敌机类:
成员变量:
int x,int y,图片,int width
int height,
成员方法:
move()
大敌机类:
成员变量:
int x,int y, 图片,int width
int height , int life
成员方法:
move()
自己的飞机类:
int x,int y, 图片,int width
int height , int life,int score,子弹
成员方法:
move()
子弹类:
int x,int y, 图片,int width
int height
成员方法:
move()
小蜜蜂类:
int x,int y, 图片,int width
int height
成员方法:
move()
把所有类中相同的成员变量和成员方法 -> 提取出来 -> 形成一个类 -> 父类
升级版:
子类 extends 父类
父类(基类):
成员变量:
int x,int y, 图片,int width
int height
成员方法:
move()
子类(衍生类/扩展类):
小敌机类:
大敌机类:
int life
自己的飞机类:
int life,子弹,int score
子弹类:
小蜜蜂类:
1.继承(extends)
1.结构:
子类(衍生类/扩展类) extends 父类/基类
2.继承的特征:
1)子类继承父类,会继承父类中所有的成员变量和成员方法
2)所有的类,都有唯一的父类
如果没有写父类,那么就会默认继承Object
3)子类可以拥有自己独有的成员变量和成员方法
并且,子类的功能一定会比父类的更强大
4)一个类只能继承一个父类,但是一个父类可以有很多个子类
特殊情况:
1.创建子类对象之前,会先创建父类对象
加载子类之前会先加载父类
2.构造方法:
调用子类构造方法之前,一定会调用父类的构造方法,默认调用父类的无参构造方法
3.子类中可以引用父类对象
4.子类和父类中有相同的成员变量时
例如: name
那么会先去运行子类中成员变量,如果没有才会去找父类中的成员变量
建议:子类和父类中不要有相同的成员变量
5.通过子类对象调用方法时
会先去找子类中有没有这个方法,如果有就实现子类中的内容
如果没有,就会往上去找父类中的方法
2.super关键词:父类对象
1)调用子类构造方法之前,一定会调用父类的构造方法,默认调用父类的无参构造方法
使用super关键词调用
2)父类中的构造方法只能调用,不能继承,默认添加super()
3)如果父类中没有无参构造方法,就需要手动调用父类中的有参构造方法
super(参数)
4)super(参数),只能放在构造方法的第一行
3.方法的重写
1)重写的前提:
必须存在父子类关系
2)语法结构:
子类中定义的方法的方法名+方法参数+返回值类型都必须和父类中完全一致
方法的重写(Override)和方法的重载(Overload)的区别:
方法的重写的前提:
必须在父子类关系中
方法的重载的前提:
必须在同一个类中
参数不一样:
个数
顺序
类型
this和super的区别:
4.抽象(abstract) abstract可以修饰: 修饰类/方法
1)抽象方法:
a.出现的前提:
例如:move()
所有的子类中的move()都有不同的实现,那也就是说明父类中的move()方法体没有意义
没有意义的东西不需要 -> 删除 -> 抽象方法 -> 加abstract
b.子类必须重写父类中的抽象方法
如果不重写,就要把自己变成抽象类
c.抽象方法的特点
1.没有方法体的方法叫抽象方法
2.抽象方法一定要存在于抽象类中
2)抽象类
a.abstract修饰的类叫抽象类
b.抽象类不能new对象,也就是不能创建类的实例化
c.抽象类也有构造方法,就是为了给子类使用的
3)abstract不能修饰成员变量,因为成员变量是有具体的类型
判断:
有抽象方法的类就是抽象类 √
抽象类就是有抽象方法的类 ×
没有抽象方法的也是抽象类 √
5.访问修饰符/权限控制符
public:公开的,公共的
protected:受保护的
default:默认的,(default)是不写的,没有的这个词
private:私有的
访问控制符可以修饰:修饰类/修饰[静态]成员变量/修饰[静态]成员方法/代码块/构造方法
自己类中: 所有的访问修饰符都可用
同包(没有任何关系的类): public default protected
不同包下(有父子关系的类): public protected
所有类(不同包下没有任何关系的类):public
访问权限的范围:
最大的是public,最小的是private
使用情况:
public:想让所有的类都可见时
protected:在父子类关系中可用
default:不常用,练习时使用
private:普通类中都可用
get/set调用
eg1:
abstrctclass包
package abstractclass;
/*
小敌机
*/
public class AirPlane extends FiyingObject{
@Override
void move() {
System.out.println("这是小敌机的移动方法");
}
@Override
void m1() {
}
@Override
void m2() {
}
}
package abstractclass;
/*
小蜜蜂
*/
public class Bee extends FiyingObject{
@Override
void move() {
System.out.println(“这是小蜜蜂的移动方法”);
}
@Override
void m1() {
}
@Override
void m2() {
}
}
package abstractclass;
/*
父类 - 飞行物类
*/
public abstract class FiyingObject {
//成员变量
/abstract/ int x;
int y;
//构造方法 - 为了给子类使用
FiyingObject(){
}
FiyingObject(int x){
}
//成员方法 - 移动的方法
//去掉方法体 -> 抽象方法 -> 加abstract
//所有子类中相同的方法 -> 为了子类代码的统一
abstract void move();
abstract void m1();
abstract void m2();
void m3(){
System.out.println("这是抽象类中的普通方法");
}
}
package abstractclass;
/*
自己的飞机类
*/
public /abstract/ class Hero extends FiyingObject{
@Override
void move() {
}
@Override
void m1() {
}
@Override
void m2() {
}
/*@Override
void move() {
System.out.println("这是自己的飞机类的方法");
}*/
}
package abstractclass;
/*
测试类
*/
public class Demo01Abstract {
public static void main(String[] args) {
//创建抽象类的对象 - 抽象类不能new 对象
//FiyingObject fiy = new FiyingObject();
Bee bee = new Bee();
bee.move();
bee.x = 1;
bee.y = 2;
Hero hero = new Hero();
hero.move();
}
}
eg2:
sub包
package sub;
/*
动物类 - 父类
*/
public class Animal extends Object{
//成员变量
int age;
int weith;
int height;
String name;
//无参构造方法
Animal(){
System.out.println(“Animal的无参构造方法”);
}
//有参构造方法
Animal(String name){
this.name = name;
System.out.println(“Animal的有参构造方法”);
}
//成员方法
String eat(String name){
System.out.println(this.name + "在吃东西");
System.out.println(this.name + "在吃东西");
System.out.println(this.name + "在吃东西");
System.out.println(this.name + "在吃东西");
System.out.println(this.name + "在吃东西");
System.out.println(this.name + "在吃东西");
return null;
}
}
package sub;
/*
小猫类 - 子类
1.子类之间本质上没有任何关系
2.唯一关系就是拥有共同的父类
/
public class Cat/ extends Animal*/{
}
package sub;
/*
小狗类 - 子类
1.子类继承父类,会继承父类中所有的成员变量和成员方法
2.所有的类,都有唯一的父类
如果没有写父类,那么就会默认继承Object
3.子类可以拥有自己独有的成员变量和成员方法
并且,子类的功能 一定会比父类的更强大
4.父类可以有很多个子类
*/
public class Dog extends Animal{
//自己的成员变量
char sex;
String name;
//无参构造方法
Dog(){
this("");
//super("小黑");
//super();调用父类的无参构造方法
System.out.println("Dog的无参构造方法");
}
Dog(String name){
//调用父类的有参构造方法
super("小黑");
//super();
//super:父类对象
//super.name = name;
this.name = name;
System.out.println("Dog的有参构造方法");
}
//自己的成员方法
void wang(){
System.out.println("小狗在叫!!!");
}
//跟父类中相同的成员方法
/String eat(String name){
// System.out.println(this.name + “在吃东西”);
System.out.println(this.name + “在吃东西”);
System.out.println(this.name + “在吃东西”);
System.out.println(this.name + “在吃东西”);
System.out.println(this.name + “在吃东西”);
System.out.println(this.name + “在吃东西”);//*
// System.out.println(this.name + “在吃东西”);//
super.eat(“小黑”);
//super.age = 21;
System.out.println(“吃完了,还吃”);
System.out.println(“继续吃”);
return null;
}*/
//重写的快捷键 Ctrl+o Alt+Ins
@Override
String eat(String name) {
return null;
}
}
package sub;
/*
测试类 - 只放主方法
*/
public class Demo01Test {
public static void main(String[] args) {
//创建小狗类的对象
Dog dog = new Dog();
//dog.name = “旺财”;
dog.age = 12;
//调用子类中的成员方法 - 继承
dog.eat(“小黑”);
System.out.println(dog.name);
dog.eat(“小黑”);
//属于Object的方法,所以可以直接调用
//dog.hashCode();
}
}
eg3:
visit包
package visit.child;
import visit.Animal;
/*
不同包下,并且没有任何关系的类 - 和Animal
/
public class Demo02Test {
public static void main(String[] args) {
//创建Animal类的对象
Animal a = new Animal();
System.out.println(“a_public:” + a.a_public);
/ System.out.println(“b_protecte:” + a.b_protecte);
System.out.println(“c_default:” + a.c_default);
System.out.println(“d_private:” + a.d_private);*/
}
}
package visit.child;
import visit.Animal;
/*
有父子类关系的类
*/
public class Dog extends Animal {
//使用 Animal类中的成员变量
public void m2(){
System.out.println("a_public:" + a_public);
//protected -> 修饰有父子类关系的类
System.out.println("b_protected:" + b_protecte);
//System.out.println("c_default:" + c_default);
//System.out.println("d_private:" + d_private);
}
}