java面向对象阶段
创建对象
类名 变量名=new 构造方法([参数])
public class Game {
Game ga=new Game();
}
变量
成员变量:定义在类中,类的属性,有默认值,通过对象访问
局部变量:定义在方法中,没有默认值,只能在方法中赋值后能用
静态常量:特殊的成员变量,有默认值,通过类名访问
构造方法
public 类名称(参数类型 参数名称){
方法体
}
public class Game {
private String name;
public Game(String name) {
//带参数的构造
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
调用构造方法,需要new对象
public class Main {
public static void main(String[] args) {
Game ga=new Game("英雄联盟");//带参数的调用
Game ga1=new Game();//无参的调用
ga1.getName();//无参调用读取方法
ga1.setName("fifaonline4");//无参调用设置方法
}
}
下面是重点
封装
封装是一种 信息隐藏技术 ,在java中通过关键字private,protected和public实现封装。
public class Game {
private String name;
private int id;
public void setId(int id) {
this.id = id;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public int getAge() {
return age;
}
private int age;
public Game(){}//无参构造
public Game(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
//有参构造
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用get()和set()方法对属性进行操作
public class Main {
public static void main(String[] args) {
//Game ga=new Game("英雄联盟");//带参数的调用
Game ga1=new Game();//无参的调用
ga1.getName();//无参调用读取方法
ga1.setName("fifaonline4");//无参调用设置方法
ga1.getAge();
ga1.setAge(5);
ga1.setName("亚索");
ga1.getName();
}
}
继承
class 父类 { }
class 子类 extends 父类 { }
格式如上
public class Game {}
public class Player extends Game{
}
重写:难点
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
public class Game() {
public void play() {
System.out.println("父类玩fafionline4");
}
}
public class Player extends Game{
@Override
public void play() {
System.out.println("子类玩英雄联盟");
}
}
那对于如何我们如何调用这个父类的方法和子类的方法
我们看new谁的对象,做决定
列如
Game g=new Game();
g.paly();//这个就是调用的父类
Player p=new Player();
p.play();//这个就是调用的子类
下面我就以我做的错题做例子
class AA {
void Show(){ System.out.println(“我喜欢Java!”);
}
class BB extends AA {
void Show(){ System.out.println(“我喜欢C++!”); }
public static void main(String[] args) {
AA a = (AA)new BB(); //这是向上转换
BB b = new BB();
a.Show();
b.Show();
}
}
[A] 我喜欢Java!
我喜欢C++!
[B] 我喜欢C++!
我喜欢Java!
[C] 我喜欢Java!
我喜欢Java!
[D] 我喜欢C++!
我喜欢C++!
Game g =new Player() ;
//子类对象可以用父类
Player p=(Player) new Game()
//父类就不能用子类,需用(子类)
重载
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
public Game(){}
public Game(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
this和super的使用
super
public void eat(){
System.out.println("父类吃饭");
}
public class Player extends Game{
@Override
public void eat() {
super.eat();
System.out.println("子类吃面");//在调用时,根据前面所说的,分为调用super().eat方法,还有一种,就是我重写的方法
}
}
this
public Game(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;//加上this为了区分实例和形参
}
多态
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
Game g =new Player() ;
如果子类重写了父类的方法,被调用时,执行重写后的内容
这里有一个我们做的一个homework
一个小游戏,做的时候没用到继承和多态
可以下来改一改
public class Hero {
private String name;
private String camp;
private String weapon;
private String skill;
private int hp=1000;
@Override
public String toString() {
return "Hero{" +
"name='" + name + '\'' +
", camp='" + camp + '\'' +
", weapon='" + weapon + '\'' +
", skill='" + skill + '\'' +
", hp=" + hp +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Hero hero = (Hero) o;
return Objects.equals(name, hero.name) &&
Objects.equals(camp, hero.camp) &&
Objects.equals(weapon, hero.weapon) &&
Objects.equals(skill, hero.skill);
}
public Hero(String name, String camp, String weapon, String skill) {
this.name = name;
this.camp = camp;
this.weapon = weapon;
this.skill = skill;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCamp() {
return camp;
}
public void setCamp(String camp) {
this.camp = camp;
}
public String getWeapon() {
return weapon;
}
public void setWeapon(String weapon) {
this.weapon = weapon;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
Player player = new Player();
Hero h1 = new Hero("关羽", "蜀国", "青龙偃月刀", "我砍");
Hero h2 = new Hero("曹操", "魏国", "倚天剑", "突突");
Hero h3 = new Hero("李白", "人类", "剑", "青莲剑歌");
Hero h4 = new Hero("李白", "人类", "剑", "青莲剑歌");
player.addHero(h1);
player.addHero(h2);
player.addHero(h3);
player.addHero(h4);
player.showAll();
System.out.println("请选择第一位要上场的任务编号");
int no1 = sc.nextInt();
Hero hero1 = player.findByNo(no1);
System.out.println("请选择第二位要上场的任务编号");
int no2 = sc.nextInt();
Hero hero2 = player.findByNo(no2);
player.battle(hero1,hero2);
}
}
public class Player {
private Hero[] list;
public Player() {
this.list = new Hero[10];
}
/*
* 添加
* */
public void addHero(Hero hero) {
//判断添加的对象是否存在
for (int i = 0; i < list.length; i++) {
if (list[i] != null && list[i].equals(hero)) {
return;
}
}
//判断是否有空位
for (int i = 0; i < list.length; i++) {
if (list[i] == null) {
list[i] = hero;
break;
}
}
}
/*
* 打印所有
* */
public void showAll() {
int i = 1;
for (Hero hero : list) {
if (hero != null) {
System.out.println(i++ + ":" + hero);
}
}
}
/*
* 得到某个Hero
* */
public Hero findByNo(int no) {
if (no <= list.length && no > 0) {
if (list[no - 1] != null) {
return list[no - 1];
}
}
return null;
}
/*
* PK
* */
public void battle(Hero h1, Hero h2) throws InterruptedException {
Random rd = new Random();
System.out.println("来自" + h1.getCamp() + "的【" + h1.getName() + "】VS来自" + h2.getCamp() + "的【" + h2.getName() + "】");
while (true) {
if (h1.getHp() <= 0) {
System.out.println(h1.getName() + "已阵亡");
break;
}
if (h2.getHp() <= 0) {
System.out.println(h2.getName() + "已阵亡");
break;
}
Thread.sleep(500);
//生成4-12之间的随机数
int randNum = rd.nextInt(9) + 4;
//先判断最小情况
if (randNum % 12 == 0) {
int hurt1 = rd.nextInt(51) + 100;//hurt1表示h1造成的伤害
int hurt2 = rd.nextInt(51) + 100;//hurt2表示h2造成的伤害
System.out.println(h1.getName() + "使用" + h1.getWeapon() + "发动" + h1.getSkill() + "对" + h2.getName() + "造成" + hurt1 + "伤害");
System.out.println(h2.getName() + "使用" + h2.getWeapon() + "发动" + h2.getSkill() + "对" + h1.getName() + "造成" + hurt2 + "伤害");
h1.setHp(h1.getHp() - hurt2);
h2.setHp(h2.getHp() - hurt1);
} else if (randNum % 3 == 0) {
int hurt1 = rd.nextInt(51) + 100;//hurt1表示h1造成的伤害
System.out.println(h1.getName() + "使用" + h1.getWeapon() + "发动" + h1.getSkill() + "对" + h2.getName() + "造成" + hurt1 + "伤害");
h2.setHp(h2.getHp() - hurt1);
} else if (randNum % 4 == 0) {
int hurt2 = rd.nextInt(51) + 100;//hurt2表示h2造成的伤害
System.out.println(h2.getName() + "使用" + h2.getWeapon() + "发动" + h2.getSkill() + "对" + h1.getName() + "造成" + hurt2 + "伤害");
h1.setHp(h1.getHp() - hurt2);
} else {
System.out.println(h2.getName() + "使用普通攻击对" + h1.getName() + "造成10伤害");
System.out.println(h1.getName() + "使用普通攻击对" + h2.getName() + "造成10伤害");
h1.setHp(h1.getHp() - 10);
h2.setHp(h2.getHp() - 10);
}
}
}
}
抽象方法
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
关键字 abstract
-
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
-
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
-
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
-
4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
-
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
与类的区别
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
枚举
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。
/*
* 定义枚举类型:星期
* */
public enum Week {
//定义一组该枚举类型的常量集合
SUN,MON,TUE,WED,THU,FRI,SAT
}