一、方法的重写(override/overriding):重新写、覆盖
1)重写:发生在父子类中,方法名相同,参数列表相同(方法签名完全相同)
2)重写方法被调用时,看对象的类型(若对象的类型是超类,则执行超类中的方法,若对象的类型是子类,则执行子类中的方法)。new 出来的是对象,即new谁就看谁
我继承了一个中餐馆
class Aoo{
void do(){
做中餐
}
}
A:我还是想做中餐------------不需要重写
class Boo extends Aoo{
}
B:我想改做西餐--------------需要重写
class Boo extends Aoo{
void do(){
做西餐
}
}
C:我想在中餐基础之上加西餐-----需要重写(先super中餐,再加入西餐)
class Boo extends Aoo{
void do(){
super.do();
做西餐
}
}
子类觉得超类的行为不够好的时候,可以重写。重写对应的是父类中的方法
重写只要被调用,铁定看对象的类型,这是一种多态的表现
super.方法名()调用超类的方法,一般:在超类的方法基础之上进行重写的时候。(是觉得超类的方法不足,额外增加别的功能)
二、重写与重载的区别
- 重写:发生在父子类中,方法名相同,参数列表相同。当派生类觉得超类的的方法不好
(一般用在派生类修改超类的方法) - 重载:发生在同一个类中,方法名相同,参数列表不同.
(是完全不同的方法,只是方法名相同而已)
三、package 和 import
package:声明包
- 作用:避免类的命名冲突(如果以类名为唯一标识的话,特别容易出现命名冲突)
- java规定:同包的类是不能同名,不同包的类是可以同名的
- 类的全称:包名.类名 包名常常有层次结构 例:a.Aoo
- 建议包名所有字母全部用小写,package声明包必须放在第一行
- 不同包进行访问的时候,可以写类名的全称也可以导入类import
- java可以同包继承也可以不同包继承
import:导入类
说明:导入包的位置位于包package的下一行
同包中的类可以直接进行访问,不同包中的类不能直接进行访问(跨包不能直接进行访问)
若想访问,比较繁琐的一个方法:写类的全称
1)建议:先 import导入类(类的全称),再访问类。
用哪个类就导入哪个类,不建议全部导入某个包的所有类import.java.,会影响性能:import java.util.
import java.util.Scanner
//java.util是包名
//Scanner是个类,这个类是在java.util这个包下的
//
java.util.Scanner scan = new java.util.Scanner(System.in);
- 调用的是有参的构造方法,System.in是个io流
- Scanner 类中有个方法时nextInt方法,没有参数,但是这个方法有返回值是int型
四、访问控制修饰符
封装的意义:隐藏一些东西,暴露一些东西
- 数据(成员变量)私有化(private)
- 行为大部分(方法)公开化(public)
- 用于实现封装的,把访问权限封装起来
- 作用:保护数据的安全
- public:公开的,任何类
- private:私有的,本类
- protected: 受保护的,只能:本类、派生类、同包类
- 默认的:什么也不写,可以本类、同包类使用
- 1.修饰类的访问权限修饰符只能是public或者默认
- 2.类中的成员(方法和成员变量)的访问权限如上四种都可以,一般用两个public和private
- 3.访问权限由大到小依次为:public > protected > 默认的 > private
//访问权限范围:
package ooday04;
//演示访问控制修饰符
public class Aoo {
public int a; //任何类
protected int b; //本类、派生类、同包类
int c; //本类、同包类
private int d; //本类
void show(){
a = 1;
b = 2;
c = 3;
d = 4;
}
}
class Boo{ //---------------演示private
void show(){
Aoo o = new Aoo();
o.a = 1;
o.b = 2;
o.c = 3;
//o.d = 4; //编译错误
}
}
package ooday04_vis;
import ooday04.Aoo;
public class Coo { //演示同包的概念
void show(){
Aoo o = new Aoo();
o.a = 1;
//o.b = 2; //编译错误
//o.c = 3; //编译错误
//o.d = 4; //编译错误
}
}
class Doo extends Aoo{ //演示protected
void show(){
a = 1;
b = 2;
//c = 3; //编译错误
//d = 4; //编译错误
}
}
四、static:静态的
1)静态变量
静态变量何时用?当所有对象所共享的数据
- 由static修饰
- 属于类,存储在方法区中,只有一份。
- 常常通过类名打点来进行访问
- 何时用:所有对象所共享的数据(图片、音频、视频等)
凡是类名打点的都是静态变量
一个类只被加载一次,方法区只会在第一次加载的时候会用
补充:成员变量分为实例变量和静态变量
重点:
- 实例变量:没有static修饰,属于对象的,存储在堆中,有几个对象就有几份.比如:new 5个对象就有5份,先创建对象再通过引用打点来进行访问(引用指的是对象)
- 静态变量:由static修饰,不属于对象,属于类的,存储在方法区中,类只有一份,所以静态变量也只有一份,通过类名打点来进行访问
public class StaticDemo {
public static void main(String[] args) {
Eoo o1 = new Eoo();
o1.show();
Eoo o2 = new Eoo();
o2.show();
Eoo o3 = new Eoo();
o3.show();
System.out.println(Eoo.b); //常常通过类名点来访问
}
}
class Eoo{ //演示静态变量
int a;
static int b;
Eoo(){
a++;
b++;
}
void show(){
System.out.println("a="+a+",b="+b);
}
}
补充:
- 方法区:.class字节码文件(包括静态变量\所有的方法)
- 先画方法区,因为先执行方法区
- 当第一次用到的时候会加载一次方法区,以后不会再加载方法区,方法区只在第一次用到的时候加载一次
2)静态方法:
①由static修饰
②属于类,存储在方法区中,只有一份。
③常常通过类名打点来进行访问
④静态方式没有隐式this传递,所以不能直接访问实例成员(包括实例变量和实例方法)
⑤何时用:方法的操作与对象无关
普通方法里面是有隐式的this
以后调用方法前面打点是类(首字母大写)还是对象(首字母小写),就能判断出静态还是动态方法
静态方法何时用
重点:静态方法中没有隐式的this,没有对象.普通方法是需要对象打点来进行访问的,所以这里是没有办法对实例方法来进行访问
![在这里插入图片描述](https://img-blog.csdnimg.cn/47937228b7c54ff7a9126a2ccdc812dc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQOayoeiTnQ==,size_20,color_FFFFFF,t_70,g_se,x_16
Arrays.copyOf()静态方法
scan.nextInt() 实例方法
//static的演示
public class StaticDemo {
public static void main(String[] args) {
Goo.plus(4,6);
}
}
//演示静态方法
class Foo{
int a; //实例变量(由对象来访问)
static int b; //静态变量(由类名来访问)
void show(){ //有隐式this
System.out.println(this.a);
System.out.println(Foo.b);
}
static void test(){
//静态方法中没有隐式this传递
//没有this就意味着没有对象
//而实例变量a是必须由对象来访问的
//所以下面的语句发生编译错误
//System.out.println(a); //编译错误
System.out.println(Eoo.b);
}
}
//演示静态方法何时用
class Goo{
int a; //对象的属性
//方法中用到了对象的属性a,意味着show()的操作与对象是有关的,不能做成静态方法
void show(){
System.out.println(a);
}
//方法中没有用到对象的属性和行为,意味着plus()的操作与对象是无关的,可以做成静态方法
static void plus(int num1,int num2){
int num = num1+num2;
System.out.println(num);
}
}
3)静态块:
静态块的执行早于构造方法的执行,静态块在类加载期间被自动执行
①由static修饰
②属于类,在类被加载期间会自动执行,一个类只被加载一次,所以静态块也只执行一次
③何时用:初始化/加载静态资源(图片、音频、视频等)
静态块作用:一旦图片、视频等做好了,就在静态块中做赋值。是给静态变量赋值的
静态块什么时候走:
加载这个类的时候,就会加载这个方法区,就把静态块执行了,new方法分配对象再去调用构造方法,但是不再去执行静态块
static {
//静态块
}
静态块最先执行且只执行一次
重点:
静态块:————初始化静态变量,给静态变量赋初始值
构造方法————初始化实例变量,给实例变量赋初始值
假设在构造方法中给img赋值__new一个对象就会读取一次图片,有100个对象就得读取100次图片,多次读取图片会影响性能
假设在静态块中给img赋值__只在加载类的时候会读取一次图片,无论new了多少个对象,只读一次,减少内存,提高性能
class Aoo{
int a ; //实例变量
static int b; //静态变量
}
实例变量是对象,存储在堆中
静态变量都是属于类的,属于类的东西都存储在方法区中
目前的图片的访问权限控制符是设置为proteced,因为还没学利用get/set方法来得到private修饰的变量
1)内存管理:我们不能控制内存,jvm自动进行管理。
堆:存储new出来的对象,包括成员变量(成员变量中的实例变量)
栈:局部变量(包括方法的参数)
方法区:.class字节码文件(静态变量,所有方法)
三块同时出现,先画方法区,先jvm加载运行.class字节码文件
main方法是静态方法
静态的方法里面只能访问静态的变量
做成静态的方法很方便,不用去new一个对象
在构造方法中给实例变量做初始化
在静态块中给静态变量做初始化
java中图片类型:
image、icon、imageIcon、BufferedImage
图片一般都公开
重写需要遵循:两同两小一大
1)两同:①方法名相同②参数列表相同
2)两小:①派生类方法的返回值类型必须小于或等于超类方法的②派生类方法抛出的异常必须小于或能与超类方法的
1.1)void和基本类型时,必须相等,一模一样。同是基本类型或者同是void
1.2)引用类型时,小于或等于
3)一大:派生类方法的访问权限必须大于或等于超类方法的 public>protected>默认的>private
引用类型的返回值大小:父类大,子类小
重写和重载的区别
1)重写:发生在父子类中,方法名相同,参数列表相同
当派生类觉得超类的行为不够好,想修改时,可以重写
2)重载:发生在同一个类中,方法名相同,参数列表不同
重载时完全不同的方法,只不过赶上方法名相同而已