JAVASE基础模块九(继承 方法重写 static super final 同名变量 代码块等)
长方形的属性
public class JuXing {
private double chang;
private double kuan;
private double mianJi;
private double zhouChang;
public JuXing() {
}
public JuXing(double chang, double kuan) {
this.chang = chang;
this.kuan = kuan;
}
public double getChang() {
return chang;
}
public void setChang(double chang) {
this.chang = chang;
}
public double getKuan() {
return kuan;
}
public void setKuan(double kuan) {
this.kuan = kuan;
}
public double getMianJi() {
return mianJi;
}
public void setMianJi(double mianJi) {
this.mianJi = mianJi;
}
public double Sizexx() {
mianJi=chang*kuan;
return mianJi;
}
public double Sizex() {
zhouChang=chang+kuan;
return zhouChang*2;
}
}
class Test {
public static void main(String[] args) {
JuXing a=new JuXing();
a.setChang(7.7);
a.setKuan(7.7);
System.out.println(a.Sizexx());
System.out.println(a.Sizex());
JuXing b=new JuXing(3.3,7.7);
System.out.println(b.Sizexx());
System.out.println(b.Sizex());
}
}
运行结果:
59.290000000000006
30.8
25.41
22.0
Process finished with exit code 0
static
public class Country {
private static String country="堪培拉";
private String name;
public Country() {
}
public Country(String country, String name) {
this.country = country;
this.name = name;
}
public Country( String name) {
this.country = country;
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void x() {
System.out.println("这是静态方法");
}
public void xx() {
System.out.println("不是静态方法");
}
}
class Tese{
public static void main(String[] args) {
Country a=new Country("x1");//"囡",
Country b=new Country("x2");//"中国",
Country c=new Country("x3");//"中国",
System.out.println(a.getName()+a.getCountry());
System.out.println(b.getName()+b.getCountry());
System.out.println(c.getName()+c.getCountry());
Country.x();
a.xx();
}
}
运行结果:
x1堪培拉
x2堪培拉
x3堪培拉
Process finished with exit code 0
改变后的运行结果:
x1囡
x2囡
x3囡
Process finished with exit code 0
- static的特点
- 随着类 class的加载而加载
- static修饰的静态域主会初始化一次
- static修饰的成员 是优先于对象而存在的
- 被类的所有对象所共享
- 被静态修饰的成员属于类 建议使用类名直接调用 不推荐使用对象.属性调用
- 静态变量也称之类变量
- static修饰的变量最好用public修饰 不推荐使用private
- 共享变量共享一个内存 当栈中的新定义对象的属性在堆内发生变化时 如果属性与静态变量属性冲突时 会覆盖方法区j静态区存放的的共享变量属性
- 同时 其他成员的默认共享变量属性也发生变化
- 定义静态的方法
- 在静态方法里 不能调用费静态的方法 静态所修饰的成员是随着类的加载而加载 是优先于对象而存在 现有的访问不到后有的
- 在静态方法里 调用不到非静态成员 只能访问静态成员 也就是
- 在静态方法里面只能访问静态所修饰的成员 不能访问非静态成员
- 在静态方法中 是不能存在this关键字的 this代表对象 是后有的
- 非静态方法 成员方法 实例方法
- 非静态方法中 即可以访问非静态的成员 也可以访问静态成员
- 对于 提供main方法作为成员入口的这个类中 我们一般不去定义成员变量与成员方法
static与main函数
- 简单的说 是为了JVM能够更加快捷方便的使用 main作为程序的入口 假设我们先不用static修饰符 那么首先我们要再找一个入口进行操作 或者对main入口所在的class类 进行 对象实例化 然后进行函数调用 但是这样每当我们进行一次对象的实例化 就要经过这些步骤 略显麻烦 因此 我们把main函数定义为static,使main函数可以直接被调用
- 对于 public修饰符 修饰main函数 个人认知是 既然是程序的入口 就不能使用private 私有权限 而protected与default又k可能会导致程序在导包时发生错误 总体来看 public是最适合修饰程序的入口的
静态变量与成员变量
- 所属不同
- 静态变量属于类,所以也称为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
- 内存中位置不同
- 静态变量存储于方法区的静态区
- 成员变量存储于堆内存
- 内存出现时间不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- 调用不同
- 静态变量可以通过类名调用,也可以通过对象调用,推荐使用类名调用
- 成员变量只能通过对象名调用
Math 类
public class Mathxx {
public static void main(String[] args) {
double m = (int) (Math.random() * 100);
System.out.println("猜呗j");
for (int i = 0; i < 10; i++) {
Scanner c = new Scanner(System.in);
int n = c.nextInt();
if (n > m) {
System.out.println("大了");
System.out.println("剩" + (10 - i) + "次了");
} else if (n < m) {
System.out.println("小了");
System.out.println("剩" + (10 - i) + "次了");
} else {
System.out.println("好吧");
break;
}
}
}
}
运行结果:
猜呗j
50
小了
剩10次了
75
小了
剩9次了
90
大了
剩8次了
80
大了
剩7次了
78
好吧
Process finished with exit code 0
代码块
- 代码块:所谓代码块,就是被一对{} 大括号所括起来的代码
- 代码块的分类:局部代码块,构造代码块,静态代码块,同步代码块
- 局部代码块
- 定义在方法中的代码块
- 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
public class xxxxxx {
public static void main(String[] args) {
{
Scanner scanner = new Scanner(System.in);
System.out.println("局部代码块");
System.out.println("局部代码块");
System.out.println("局部代码块");
System.out.println("局部代码块");
}
}
}
运行结果:
局部代码块
局部代码块
局部代码块
局部代码块
Process finished with exit code 0
-
构造代码块
- 定义在类中 方法外的代码块
- 在创建的对象时 构造代码块会执行 而且优先于构造方法执行
-
静态代码块
- 定义在类中方法外的代码块
- 被static所修饰,随着类的加载而加载,最早执行,且只执行一次
class xxxxxx { public static void main(String[] args) { MyTestxxx student = new MyTestxxx(); System.out.println("============================="); MyTestxxx student2 = new MyTestxxx(); } } class MyTestxxx { static int num = 777; static { System.out.println("这就是静态代码块"); System.out.println(num); } { System.out.println("这就是构造代码块"); } public MyTestxxx() { System.out.println("这是构造方法"); } } 运行结果: 6这就是静态代码块 777 这就是构造代码块 这是构造方法 ============================= 这就是构造代码块 这是构造方法 Process finished with exit code 0
题目分析
A:看程序写结果
class Student {
static {
System.out.println("Student 静态代码块"); //3
}
{
System.out.println("Student 构造代码块"); //4 6
}
public Student() {
System.out.println("Student 构造方法");//5 7
}
}
class StudentDemo {
static {
System.out.println("StudentDemo的静态代码块"); //1
}
public static void main(String[] args) {
System.out.println("我是main方法"); //2
Student s1 = new Student();
Student s2 = new Student();
}
}
1.首先执行static {System.out.println("StudentDemo的静态代码块"); //1}
2.接着进行main函数顺序操作System.out.println("我是main方法"); //2
3.接着进行s1的实例化static {System.out.println("Student 静态代码块"); //3}
4.接着进行s1的构造代码块{ System.out.println("Student 构造代码块"); //4}
5.接着进行s1的构造方法 public Student() { System.out.println("Student 构造方法");//5 }
6.接着进行s1的构造代码块{ System.out.println("Student 构造代码块"); //6}
7.接着进行s1的构造方法 public Student() { System.out.println("Student 构造方法");//7 }
继承
- JAVA中继承的特点
- JAVA中只支持单继承 一个子类只能有一个父类 但是支持多继承
- JAVA中自雷智能继承父类非私有的 私有成员子类无法继承
- 构造方法不参与继承
- 继承 就是把多个子类的共性部分 向上抽取到父类当中 以实现代码的复用性与维护性
- 继承的好处
- 提高了代码的复用性
- 提高了代码的维护性
- 让类与类之间产生了关系,是多态的前提
- 继承的弊端
- 类的耦合性增强了
- 开发的原则:高内聚,低耦合
- 耦合:类与类的关系
- 内聚:就是自己完成某件事情的能力
- Java中类的继承特点
- Java只支持单继承 不支持多继承 有些语言是支持多继承,格式:extends 类1,类2,…
- Java支持多层继承(继承体系)
- 继承的注意事项
- 子类只能继承父类所有非私有的成员(成员方法和成员变量)
- 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法
- 不要为了部分功能而去继承
同名变量问题
public class TongMing {
public static void main(String[] args) {
Zi z=new Zi();
z.show(77);
}
}
class Fu{
int num=333;
}
class Zi extends Fu{
int num=777;
public void show(int num){
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
运行结果:
77
777
333
Process finished with exit code 0
学生老师继承类
public class Person {
String name="姓名";
int age=33;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Teacher extends Person{
public void teach(){
System.out.println("教书");
}
}
class Student extends Person{
public void study(){
System.out.println("学习");
}
}
class Test{
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.age);
System.out.println(student.name);
student.study();
Teacher teacher = new Teacher();
System.out.println(teacher.age);
System.out.println(teacher.name);
teacher.teach();
}
}
33
姓名
学习
33
姓名
教书
Process finished with exit code 0
super 关键字
- JAVA继承体系中的顶层父类都是Object类
- 代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
- this与super的区别
- this 代表的是本类对象的引用 super 代表的是父类存储空间的标识
- this.成员变量 调用本类的成员变量 super.成员变量 调用父类的成员变量
- this(…) 调用本类的构造方法 super(…) 调用父类的构造方法
- this.成员方法 调用本类的成员方法 super.成员方法 调用父类的成员方法
父类变量与方法的调用
- 父类没有无参构造方法
- 在父类中添加一个无参的构造方法
- 子类通过super去显示调用父类其他的带参的构造方法
- 子类通过this去调用本类的其他构造方法
- 本类其他构造也必须首先访问了父类构造
- super(…)或者this(….)必须出现在第一条语句上
方法重写
- 当子类出现了和父类一模一样的方法时 (方法名,方法参数,返回值类型一样)
- 这种情况会发生方法覆盖现象 子类方法会覆盖父类方法
- 原因
- 有时候子类对父类的方法实现并不满意 会在子类中对父类的方法进行重写 扩展或者修改方法
public class MyTestc {
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat();
cat.sleep();
Dog dog = new Dog();
dog.eat();
dog.sleep();
}
}
class animal{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Cat extends animal{
public void eat(){
System.out.println("吃鱼去了");
}
}class Dog extends animal{
public void eat(){
System.out.println("吃狗去了");
}
}
运行结果:
吃鱼去了
睡觉
吃狗去了
睡觉
Process finished with exit code 0
-
对父类功能的扩展
public class Phone { public void call() { System.out.println("打电话"); } public static void jing() { System.out.println("换手机"); } } class Iphone extends Phone { public void call() { super.call(); System.out.println("解锁新功能:疯狂砸核桃"); } } class Test { public static void main(String[] args) { Iphone iphone = new Iphone(); Phone.jing(); iphone.call(); } }
运行结果: 换手机 打电话 解锁新功能:疯狂砸核桃 Process finished with exit code 0
-
注意事项
- 父类的私有方法 不能重写 私有方法无法继承 无法重写
- 构造方法不继承 不重写
- 子类在重写父类方法时 方法的权限修饰符不能比父类低(public–protected–缺省–private)但是可以高于父类
- 静态方法不参与重写
final 修饰符
- 最终的 可以修饰变量 方法 类
- 修饰变量 此变量为一个常量 自定义常量 常量名一般大写
- 修饰方法 此方法不能再被重写
- 修饰类 此类不能被继承
- 总结
- final修饰 基本数据类型 该值无法被再次改变
- final修饰 引用数据类型 该地址值无法再被改变
方法区存放方法 栈中进行对象实例化 堆中进行对象的属性操作
方法区分为了静态方法区与静态方法区 其余类似