面向对象第三天(Java)
##今天的主要内容是继承(extends)
##方法重写(@Override)
##构造函数和super
##final关键字
1、对昨天内容的补充:随机数的生成与数据类型的强行转换
package com.hwadee;
public class Random1 {
public static void main(String[] args) {
double r1=Math.random();//Math.random()会生成大于等于0.0并且小于1.0的伪随机数
System.out.println(r1);
System.out.println("\n"+"--------------"+"\n");
int r2=(int)(Math.random()*27)+1;//生成大于等于1并且小于28的伪随机整数
System.out.println(r2);
}
}
2、继承:继承是面向对象程序的一个基本特征,通过继承可以实现父子关系,以及代码的复用。子类可以继承父类中访问权限设定为public、protected的成员变量和方法,但是不能访问父类中权限为private的成员变量和方法。对同一个包中的父类,可以访问父类中权限default的方法。
instance of关键字用来判断一个对象是否是指定类所创建的实例,返回值是boolean。
3、重写:重写方法就是在子类中重新定义父类中已有的方法。
要求:(1)在子类中的重写方法和父类中的被重写方法,两个方法名称和参数列表必须相同。
(2)子类中重写方法的访问权限必须大于或等于父类中被重写方法的访问权限,否则编译报错。(public > protected > default > private)。
(3)子类中重写方法的返回值类型必须是父类中方法方法的返回值类型或该类型的子类,不能返回比父类更大范围的数据类型。
(4)子类中重写方法不能比父类中被重写方法产生更多的异常类型。
(5)父类的构造函数是不能子类继承的,因此不能在子类中重写。但是,在子类中可以使用super关键字访问父类中的构造函数。
4、this关键字:代表当前对象的引用,谁来调用我,我就代表谁。
super关键字:代表当前对象的父类的引用。
使用子类的对象来调用被重写方法,使用就近原则
关于继承和重写的代码学习:
package com.hwadee;
/**
* 不能在静态static方法中使用super关键字
*/
public class TestInherit {
public static void main(String[] args) {
Son s=new Son();
String c1 = s.getCar();
System.out.println(c1);
String h1 = s.getHouse();
System.out.println(h1);
int m1 = s.getMoney();
System.out.println(m1);
String computer = s.getComputer();
System.out.println(computer);
s.playGame();
// String t2 = s.getTextBook();
// System.out.println(t2);
s.playPoke("接下来就是见证奇迹的时刻");
System.out.println("\n"+"-------------------"+"\n");
Father f=new Father();
String c2 = f.getCar();
System.out.println(c2);
String h2 = f.getHouse();
System.out.println(h2);
int m2 = f.getMoney();
System.out.println(m2);
// String t1 = f.getTextBook();
// System.out.println(t1);
f.playPoke("王炸");
//父类自己调用自己的构造函数,子类不能继承父类的构造函数
new Father(40, "老薛");
}
}
class Father{
int money=30000;
String house="小木屋";
String car="自行车";
int age;
String name;
//private对日记本进行私有化,set...get..接口也私有化,则父类子类都不能调用
private String textBook="日记本";
private String getTextBook() {
return textBook;
}
private void setTextBook(String textBook) {
this.textBook = textBook;
}
public Father() {
}
public Father(int age,String name) {
this.age=age;
this.name=name;
System.out.println("父类的姓名:"+name+",父类的年龄:"+age);
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public String getHouse() {
return house;
}
public void setHouse(String house) {
this.house = house;
}
public String getCar() {
return car;
}
public void setCar(String car) {
this.car = car;
}
public void playPoke(String words) {
System.out.println("玩一玩斗地主,"+words);
}
}
/*
* Inherit--->extends
* 1 java中继承是单继承。也就是说:一个子类最多只有一个父类!不允许多继承
* 2 一个父类可以有多个子类
* 3 在Java中继承的关键字是extends(不是我们常用的inherit)
* 4 class SubClass extends SuperClass{}
* 5 子类可以有属于自身特有的成员变量和成员方法
* 6 父类的构造函数不能被子类继承
*/
class Son extends Father{
int money=100;
String computer="联想";
public void setComputer(String computer) {
this.computer=computer;
}
public String getComputer() {
return computer;
}
public void playGame() {
System.out.println("会打游戏");
}
//重写 @Override 注解
//子类的方法名与父类相同!并且输入参数都完全一样!
//至于方法里面具体怎么做,子类完全可以自己决定
@Override
public void playPoke(String words) {
System.out.println("玩玩魔术扑克,"+words);
System.out.println("这是父类的钱:"+super.money);
System.out.println("这是我自己的钱:"+money);
super.playPoke("这是父类的扑克");
}
}
5、重要面试题:方法重写和重载的区别
重写用于继承关系的父子类中,不能用于同一个类中。重写用于更改父类中方法的行为,或者是实现接口中的方法。
重写特点:函数名必须相同、参数列表必须相同。子类的返回值类型要等于或者小于父类的返回值等,子类的作用域不能小于父类中方法的作用域,子类抛出的异常类型不能大于父类中方法的异常类型。
重载通常用于同一个类中。重载用于为一个行为提供多种实现方式。
重载特点:函数名相同,参数列表不同,与访问控制符、返回值类型等无关。
6、super表示对当前对象的父类对象的一个引用,用于访问父类的属性、父类的方法和父类的构造方法。
this和super很像,this指向当前对象,super指向当前对象的父类。this和super只能在对象实例中使用,不能在静态方法中使用。
在子类的构造函数中,如果没有显示地调用父类中的构造函数,那么默认会调用父类中的无参构造函数。如果父类中没有无参构造函数,则编译报错。
如果在子类中使用super显式调用父类中的构造函数,那么编译器不会添加的调用父类中无参构造函数的代码。调用父类构造函数的super只能放在子类的构造函数的第一行,且只能调用一次。
对super的使用代码:
package com.hwadee;
/**
* 1 默认情况下,在调用子类的构造方法的时候会先调用父类的无参构造方法!
* 2 等同于显式地调用了super();
* 3 super(参数1,参数2.....)
* 4 在构造方法中调用super必须将其放到方法体的第一行!
*/
public class SuperAndConstructor {
public static void main(String[] args) {
Hashiqi h1 = new Hashiqi();//调用无参构造方法
Hashiqi h2 = new Hashiqi("erha");//调用带参构造方法
}
}
class Dog {
int legs = 4;
int eyes = 2;
String name = "Dog name";
public Dog() {
System.out.println("这是Dog的无参构造方法,"+name);
}
public Dog(String name) {
this.name = name;
System.out.println("这是Dog的带参数的构造方法," + name);
}
}
class Hashiqi extends Dog {
public Hashiqi() {
System.out.println("这是Hashiqi的无参构造方法,"+name);
}
public Hashiqi(String name) {
// super();
super("sss");// 调用父类的带参构造方法
this.name = name;
System.out.println("这是Hashiqi的带参数的构造方法," + name);
}
}
7、final关键字主要用于修饰类、属性、方法,以及方法的形参。final在类之前,表示该类不能被继承。final在方法之前,表示该方法不可被重写。final在变量之前,表示该变量不可被修改,就是一个常量。总之:被final修饰的东西不可再修改。
在实际项目中,final关键字一般和static关键字结合使用。这样可以使常量优先加载,不必等到创建对象的时候再初始化,而且访问时不需要事先创建对象实例,直接使用类名就可以访问。
如果父类中函数不想被子类继承并重写,可以将该函数使用final修饰。
今天所学的内容贯通在一起的代码展示:
package com.hwadee;
/**
* 1 默认情况下,在调用子类的构造方法的时候会先调用父类的无参构造方法!
* 2 等同于显式地调用了super();
* 3 super(参数1,参数2.....)
* 4 在构造方法中调用super必须将其放到方法体的第一行!
*/
public class SuperAndConstructor {
public static void main(String[] args) {
Hashiqi h1 = new Hashiqi();//调用无参构造方法
Hashiqi h2 = new Hashiqi("erha");//调用带参构造方法
}
}
class Dog {
int legs = 4;
int eyes = 2;
String name = "Dog name";
public Dog() {
System.out.println("这是Dog的无参构造方法,"+name);
}
public Dog(String name) {
this.name = name;
System.out.println("这是Dog的带参数的构造方法," + name);
}
}
class Hashiqi extends Dog {
public Hashiqi() {
System.out.println("这是Hashiqi的无参构造方法,"+name);
}
public Hashiqi(String name) {
// super();
super("sss");// 调用父类的带参构造方法
this.name = name;
System.out.println("这是Hashiqi的带参数的构造方法," + name);
}
}