面向对象常见问题
1.子类成员变量和父类成员变量同名,且需要super访问父类的同名成名变量
什么类型引用了就得到谁的成员变量
2.protected关键字使用和注意事项
使用:可以在本类、本包、子类中可以使用(本包或者别的包都可以)
现在修饰的内容是否在里边可以用,子类中有
3.成员方法调用过程
任何程序的入口都是main方法。当启动main方法就在栈内存中申请一个空间,执行成员方法时再给成员方法申请一个空间。成员方法执行完毕释放内存,main方法结束对应的main对应的空间也释放
4.super内存使用情况
但new子类在堆区申请一个内存。除了父类的拥有的信特征还有自己独立的特征。使用super就可以访问子类中的父类所拥有的特征
5.单例模式构造器为什么不能加static
如果构造器可以加static,而static是类层级。类层级随着类的加载而准备就绪,构造方法意义在于给每个对象进行不同的初始化
如果加了static构造方法就无法给每个对象进行不同的初始化。而且静态成员不能访问非静态成员。所有不可以加static
6.枚举语法为什么使用 ,逗号,不能使用;分号。
比如:声明两个int变量 int a; int b; 如果用,逗号表示int a,b 枚举多个所以用逗号
7.普通内部类和静态内部类使用
内部类就是当一个类存在的价值仅仅是为当前类服务的,静态和普通体现于对象层级还是类层级
8.final修饰的变量会将它的值存入常量池吗?
只要是固定的值都会放入常量池。
局部内部类访问的 外部方法中的局部变量为啥要用final修饰?
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
Object[] objects = new Object[5];
test(objects);
System.out.println(Arrays.toString(objects));
}
/**
* 局部变量的生命周期:方法内声明开始,方法结束,局部变量死亡
* 局部内部类的生命周期:方法内创建对象开始,方法结束,局部内部类不会死亡,
* 当局部内部类的对象的全部引用取消之后,局部内部类才会死亡
* 正常情况下
* 1.局部内部类在方法内创建对象,在方法结束后,如果局部内部类的对象没有被外部所引用,则局部内部类死亡
* 局部内部类生命周期:方法内声明则开始,方法结束则结束
* 局部变量生命周期:方法内声明则开始,方法结束则结束
* 有方法外部调用局部内部类对象
* 2.从外部引入一个外部对象,这个外部对象将局部内部类对象存入这个外部对象内部,
* 则这个局部内部类对象被外部对象所引用,则外部对象可以任意使用这个局部内部类对象
* 局部内部类生命周期:方法内声明则开始,来自方法外部的引用全部断开,则局部内部类对象死亡
* 局部变量生命周期:方法内声明则开始,方法结束则结束
* 问题:局部内部类调用局部变量,如果局部变量死亡了,还能调用么?
* 当然不能
* 解决:当编译器发现局部内部类调用局部变量的时候,需要将局部变量copy一份到局部内部类中
* 必须保证原局部变量和copy后的局部变量一致,那么必须保证原局部变量不可修改,所以final
*/
public static void test(Object[] objects){
final Date date = new Date();
class Demo{
public String toString(){
return date.toString();
}
}
Demo demo = new Demo();
System.out.println(demo);
objects[0]=demo;
}
public static void test(){
final Date date = new Date();
class Demo{
public String toString(){
return date.toString();
}
}
Demo demo = new Demo();
System.out.println(demo);
}
9.常量优化机制
比如:你给我一个 1+2; 那编译器就直接存放 一个3;final也是固定的。就直接一步到位。
10.
当new point 对象是在堆内存申请一个内存地址,因为引用只能记录地址。记录地址需要再在对应的堆内存中申请一个内存输入数据
11.为什么所有的局部变量都在栈内存
因为当调用方法中局部变量使用完毕就不需要了,所以这种数据放在栈内存中,方便管理
12.Scanner中next()和nextLine()的区别
while (true) {
//scanner的next()和nextLine()区别
//1.next(),该方法用来读取控制台输入的字符串,以读取到的第一个有效字符开始,到第一个空格/tab键为止,结束读取,无法读取空格
//2.nextLine(),可以读取空格
System.out.println("请输入");
Scanner sc = new Scanner(System.in);
// String next = sc.next();
/**
* 如果输入的是"123",则输出的是 "123"
* 如果输入的是" 123",则输出的是 "123"
* 如果输入的是" 123 ",则输出的是 "123"
* 如果输入的是" 123 123",则输出的是 "123"
*/
// System.out.println("next():"+next);
// String nextLine = sc.nextLine();
/**
* 如果输入的是"123",则输出的是 "123"
* 如果输入的是" 123",则输出的是 " 123"
* 如果输入的是" 123 ",则输出的是 " 123 "
* 如果输入的是" 123 123",则输出的是 " 123 123"
*/
// System.out.println("nextLine():"+nextLine);
/**
* 问题1.next会丢失字符
* 请输入
* 123 123
* next()+nextLine():123 123
*/
// String next = sc.next();
// String nextLine = sc.nextLine();
// System.out.println("next()+nextLine():"+next+nextLine);
/**
* 问题2:next的穿透性
* 请选择【1】添加学员
* 1
* 输入的是1
* 请输入学员姓名
* 学员姓名:
* 输入一次,会被扫描两次,next()会穿透到nextLine()
* 解决方案:next()+nextLine()
*/
System.out.println("请选择【1】添加学员");
String next = sc.next();//enter键留在缓冲区
System.out.println("输入的是"+next);
if("1".equals(next)){
System.out.println("请输入学员姓名");
String nextLine = sc.nextLine();//直接读取缓冲区的enter键
System.out.println("学员姓名:"+nextLine);
}
}