知识和问题整理
- 1.利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
- 2.基本数据类型、包装类转化为String?String转化为基本数据类型、包装类
- 3.为什么使用向下转型?
- 4.使用向下转型的注意点是什么?
- 5.instanceof的使用
- 6.谈谈你对封装性的理解?
- 7.谈谈你对继承的理解?
- 8.谈谈你对多态的理解?
- 9.数组也是object的一个子类
- 10.判断如下程序的运行结果
- 11.Java中使用JUnit单元测试对类有哪些要求?
- 12.static关键字的使用
- 14.开发中,如何确定一个属性是否声明为static的?
- 15.开发中,如何确定一个方法是否要声明为static的?
- 16.static使用样例
- 17.什么是设计模式?
- 18.什么是单例设计模式?有哪几种方式,请给出样例实现代码。
- 19.比较饿汉式和懒汉式的优缺点
- 20.单例模式的优点
- 21.单例设计模式的应用场景
- 22.main()方法的使用说明:
- 23.代码块可以使用哪些修饰符修饰?可以分为哪几种?加载顺序、内部可以调用哪些属性或者方法?
- 24.属性赋值的先后顺序
- 25.在子父类继承的情况下,静态代码块、动态代码块、构造器的执行顺序是什么?
- 26.final
- 27.查看如下代码是否会报错
- 28.abstract关键字可以用来修饰哪些部分?作用和注意点分别是什么?
- 29.匿名子类对象
- 30.模板方法涉及模式
- 31.接口
- 32.抽象类和接口有哪些异同?
- 33.接口匿名实现类
- 34.代理模式(案例:明星和经纪人)
- 35.代理模式的应用场景
- 36.工厂模式
- 37.排错
- 38.排错
- 39.样例
- 40.Java8中接口的新特性
- 41.内部类
- 42.成员内部类
1.利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。而向量类java.util.Vector可以根据需要动态伸缩。
创建Vector对象:Vector v=new Vector();
给向量添加元素:v.addElement(Object obj); //obj必须是对象取出向量中的元素:Objectobj=v.elementAt(0);
注意第一个元素的下标是0,返回值是Object类型的。
计算向量的长度:v.size();
若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等
public class ScoreTest {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
Vector v=new Vector();
int max=0;
for(;;) {
System.out.println("请输入学生成绩信息 ,如果像停止请输入负数:");
int temp=scan.nextInt();
if(temp<0) {
break;
}else if(temp>100){
System.out.println("输入数据有误,请继续输入!");
continue;
}else {
if(temp>max)
max=temp;
Integer temp1=new Integer(temp);
v.add(temp1);
}
}
for(int i=0;i<v.size();i++) {
int temp2=((Integer) v.get(i)).intValue();
if(max-temp2<10) {
System.out.println("等级A");
}else if(max-temp2<20) {
System.out.println("等级B");
}else if(max-temp2<30) {
System.out.println("等级C");
}else {
System.out.println("等级D");
}
}
}
}
2.基本数据类型、包装类转化为String?String转化为基本数据类型、包装类
1)String.valueOf(XXX xx)
Integer test=new Integer("12");
String test1=String.valueOf(test);
String test2=test.toString();
2)parseXxx()
Integer test4=Integer.parseInt(test1);
3.为什么使用向下转型?
有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能调用。所以必须使用向下转型。
4.使用向下转型的注意点是什么?
1)使用强转时,可能出现ClassCastException的异常
2)为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进instanceof的判断,一旦返回true,就进行向下转型,如果返回false,不进行向下转型。
5.instanceof的使用
1)a instanceof A:判断对象a是否是类型A的实例,如果是,返回true,如果不是,返回false.
2)如果a instanceof A 返回true,则 a instanceof B 也返回true,其中类B是类A的父类。
3)要求a所属的类与类A必须是子类和父类的关系,否则编译出错。
6.谈谈你对封装性的理解?
根据需要确定属性和方法是否需要对外暴露,通过权限修饰符进行控制。
7.谈谈你对继承的理解?
继承指的是子类继承父类,主要是实现属性和功能的重用性,在继承的过程中还可以继承父类的父类。
8.谈谈你对多态的理解?
主要是为了实现代码的通用性。在运行的时候根据需要运行对应类的方法。
例如:JDBC
多态性还涉及到抽象类、接口的使用
9.数组也是object的一个子类
10.判断如下程序的运行结果
public void test3(){
String s="abc";
s=null;
System.out.println(s);//1
System.out.println(s.toString());//2
}
运行结果:
1.null
2.NullPointerException
11.Java中使用JUnit单元测试对类有哪些要求?
1)此类事public的
2)此类提供公共的无参的构造器
3)方法权限是public,没有返回值,没有形参
12.static关键字的使用
1.静态的,可用于修饰属性、方法、代码块、内部类
2.静态变量(类变量):使用static修饰的属性
类变量和实例变量的区别:
1)类变量所有的类共用一份变量
2)实例变量,类各自拥有
3.static修饰属性的其他说明:
1)静态变量随着类的加载而加载,类的加载只有一次,早于对象的创建,则静态变量在内存中也只会存在一份,存在方法区的静态域中。
2)可以通过"类.静态变量"的方式进行调用,类不可以调用实例变量
4.静态方法
1)随着类的加载而加载,在静态方法中只能调用静态方法或属性,类不能直接调用实例方法。
2)在静态方法中,不能使用this关键字、super关键字
14.开发中,如何确定一个属性是否声明为static的?
属性是可以被多个对象所共享的,不会随着对象的不同而不同。
类中的常量也常常声明为static
15.开发中,如何确定一个方法是否要声明为static的?
1)操作静态属性的方法,通常设置为static的
2)工具类中的方法,习惯上声明为static的,比如:Math、Arrays、Collections
16.static使用样例
public class CricleTest {
public static void main(String[] args) {
Circle c1=new Circle();
Circle c2=new Circle();
System.out.println("c1的id:"+c1.getId());
System.out.println("c1的id:"+c2.getId());
System.out.println("创建的园的个数为:"+Circle.getTotal());
}
}
class Circle{
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public int getId() {
return id;
}
private int id;
private static int total;
public static int getTotal() {
return total;
}
public static void setTotal(int total) {
Circle.total = total;
}
private static int init=1001;
public Circle(){
id=init++;
total++;
}
public double findArea(){
return 3.14*radius*radius;
}
}
17.什么是设计模式?
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。”套路”
18.什么是单例设计模式?有哪几种方式,请给出样例实现代码。
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
1.饿汉式
public class SingleTest {
public static void main(String[] args) {
Bank bank=Bank.getInstance();
bank.getNum();
Order order=Order.getInstance();
Order order1=Order.getInstance();
System.out.println(order==order1);
}
}
class Bank{
private Bank() {
}
private static Bank instance=new Bank();
public static Bank getInstance() {
return instance;
}
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
2.懒汉式(注意线程的安全)
class Order {
private Order() {
}
private static Order instance = null;
public static Order getInstance() {
if(instance==null) {
synchronized(Order.class) {
if (instance == null)
instance = new Order();
return instance;
}
}
return instance;
}
}
19.比较饿汉式和懒汉式的优缺点
饿汉式:
坏处:对象加载时间过长
好处:饿汉式是线程安全的
懒汉式:
坏处:延迟对象的创建
需要涉及到多线程修改,来使得线程安全
20.单例模式的优点
减少系统性能开销
21.单例设计模式的应用场景
1.网站的计数器
2.应用程序的日志应用
3.数据库连接池
4.读取配置文件的类
5.Application也是单例的典型应用
6.Windows的TaskManager (任务管理器)就是很典型的单例模式
7.Windows的RecycleBin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
22.main()方法的使用说明:
1.main()方法作为程序的入口
2.main()方法也是一个普通的静态方法
3.main()方法也可以作为与控制台交互的方式
23.代码块可以使用哪些修饰符修饰?可以分为哪几种?加载顺序、内部可以调用哪些属性或者方法?
1.分为静态代码块和非静态代码块
2.静态代码块
1)随着类的加载而执行,而且只执行一次
2)可以用来初始化类的信息
3)静态代码块按顺序执行
4)只能调用静态的属性、静态的方法(可以有输出语句),不能调用非静态的结构
3.非静态代码块
1)随着对象的创建而执行,每创建一个对象都会执行一次
2)可以对对象的属性进行初始化
3)按顺序执行
4)可以调用静态\非静态方法\属性
4.两者的比较
1)静态代码块优先于动态代码块创建
24.属性赋值的先后顺序
1.默认初始化
2.显示初始化\在代码块中赋值
3.构造器中初始化
4.有了对象之后,“对象.属性”"对象.方法"赋值
25.在子父类继承的情况下,静态代码块、动态代码块、构造器的执行顺序是什么?
1.静态代码块:由父及子初始化
2.动态代码块后构造器(类中构造器的调用顺序按具体代码看):由父及子初始化
26.final
1.final可以用来修饰的结构:类、方法、变量
2.final用来修饰一个类:此类不可以被其他类所继承
比如:Object类中getClass()
3.final用来修饰方法,表名此方法不可以被重写,比如:Object类中的getClass();
4.final用来修饰成员变量,此时的"变量"就称为是一个常量,一旦赋值就不可以修改,对象创建之后也不可以对修饰的变量再赋值
1)final不能默认初始化,即不能不在任何地方赋值就使用
2)final可以显示初始化
3)final可以在代码块中赋值
4)在构造器中初始化
6.final修饰局部变量
public void show(){
final int NUM=10;
}
public void show(final int num){
System.out.println(num);//在传参的时候赋值,后面无法赋值
}
statci final用来修饰属性:全局常量
27.查看如下代码是否会报错
public class Something {
public int addOne(final int x) {
return ++x;//报错
//return x + 1;
}}
public class Something {
public static void main(String[]args) {
Other o=new Other();
new Something().addOne(o);
}
public void addOne(final Other o) {//正常
//o = new Other();报错
o.i++;}
}
class Other {
public int i;
}
28.abstract关键字可以用来修饰哪些部分?作用和注意点分别是什么?
1.abstract修饰类:抽象类
1)此类不能实例化
2)抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
3)开发中,都会提供抽象类的子类,让子类对象实例化
2.abstract修饰方法:抽象方法
1)抽象方法只有方法的声明,没有具体方法体
2)包含抽象方法的类,一定是一个抽象类,反之,抽象类的中可以没有抽象方法
3)若子类重写了父类中的所有的抽象方法,此子类方可实例化
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
3.注意点
1)abstract不能用来修饰:属性、构造器等结构
2)abstract不能用来修饰私有方法、静态方法、final方法、final的类
29.匿名子类对象
创建了一匿名子类的对象,Person为抽象类
Person woman=new Person() {
public int getI() {
// TODO Auto-generated method stub
return 0;
}
};
30.模板方法涉及模式
当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
样例代码:
public class Main {
public static void main(String[] args) {
Template subTemplate=new SubTemplate();
subTemplate.spendTime();
}
}
abstract class Template{
public void spendTime(){
long start=System.currentTimeMillis();
code();
long end=System.currentTimeMillis();
System.out.println("花费的时间为:"+(end-start));
}
public abstract void code();
}
class SubTemplate extends Template{
public void code(){
for(int i=2;i<=1000;i++){
boolean isFlag=true;
for(int j=2;j<=Math.sqrt(i);j++){
if(i%j==0){
isFlag=false;
break;
}
}
if(isFlag){
System.out.println(i);
}
}
}
}
31.接口
1.接口就可以得到多重继承的效果
2.接口中使用interface来定义
3.Java中,接口和类是并列的两个结构
4.如何定义接口:定义接口中的成员
4.1 JDK7及以前,只能定义全局变量和抽象方法
全局变量:public static final(可以省略个别修饰)
抽象方法:public abstract(可以省略个别修饰)
5.接口中不能有构造器
6.接口通常让类用(implements)的方式去实现(抽象类或者类)
public class InterfaceTest{
public static void main(String[] args) {
Flyable plane=new Plane();
plane.fly();
}
}
interface Flyable{
public static final int MAX_SPEED=7900;
int MIN_SPEED=1;
public abstract void fly();
void stop();
}
class Plane extends Test2 implements Flyable,Test{
public void fly(){
System.out.println("通过引擎起飞");
}
public void stop(){
System.out.println("驾驶员减速停止");
}
}
abstract class Kite implements Flyable{
public void fly(){
}
public void color() {
System.out.println("color");
}
}
interface Test{
int i=0;
}
class Test2{
}
7.接口和接口之间也可以实现多继承
interface AA{
public void method1();
}
interface BB{
public abstract void method1();
}
interface CC extends AA,BB{
public void method1();
}
class EE implements CC{
public void method1() {
}
}
8.接口实际上定义了一种规范
32.抽象类和接口有哪些异同?
相同点:
1.本身都不能实例化
2.在使用中都可以体现多态性
不同点:
1.抽象类可以有构造器,用于给子类继承,接口不能有构造器
2.关键字不同,抽象类:abstract修饰类,接口:interface修饰
3.抽象类的子类只能用extends关键字来继承,且是单继承;接口的子类可以用关键字implements同时实现多个接口,接口的子接口可以同时extends多个接口
4.抽象类中的全局属性可以根据需要设置修饰符,接口中只能有public static final 修饰的属性。
5.接口中的普通类成员方法不能有具体实现的方法体,如果一定要实现某些方法,则只能定义为静态、默认方法,抽象类普通类成员方法可以有具体实现的方法体。
33.接口匿名实现类
示例代码:
public class InterfaceTest2 {
public static void main(String[] args) {
Computer computer=new Computer();
computer.transferData(new Flash());
USB usb=new USB() {
@Override
public void start() {
System.out.println("U1盘开始工作");
}
@Override
public void stop() {
System.out.println("U1盘开始工作");
}
};
computer.transferData(usb);
computer.transferData(new USB() {
@Override
public void start() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
});
}
}
class Computer{
public void transferData(USB usb) {
usb.start();
System.out.println("工作中");
usb.stop();
}
}
interface USB{
void start();
void stop();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开始工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印机开始工作");
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
34.代理模式(案例:明星和经纪人)
public class NetworkTest {
public static void main(String[] args) {
Server server=new Server();
new ProxyServer(server).browse();;
}
}
interface NetWork{
public void browse();
}
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work) {
this.work = work;
}
public void check() {
System.out.println("联网之前的检查工作!");
}
@Override
public void browse() {
check();
work.browse();
}
}
35.代理模式的应用场景
安全代理:屏蔽对真实角色的直接访问。
远程代理:通过代理类处理远程方法调用(RMI)
延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
分类
1)静态代理(静态定义代理类)
2)动态代理(动态生成代理类)
3)JDK自带的动态代理,需要反射等知识
36.工厂模式
样例代码1:
interface Car {
void run();
}
class Audi implements Car {
public void run() {
System.out.println("奥迪在跑");
}
}
class BYD implements Car {
public void run() {
System.out.println("比亚迪在跑");
}
}
class CarFactory {
//方式一
public static Car getCar(String type) {
if ("奥迪".equals(type)) {
return new Audi();
} else if ("比亚迪".equals(type)) {
return new BYD();
} else {
return null;
}
}
//方式二
// public static Car getAudi() {
// return new Audi();
// }
//
// public static Car getByd() {
//return new BYD();
// }
}
public class Client02 {
public static void main(String[] args) {
Car a = CarFactory.getCar("奥迪");
a.run();
Car b = CarFactory.getCar("比亚迪");
b.run();
}
}
特点:把调用者与创建者分离,对于增加新产品,不修改代码的话,是无法扩展的。违反了开闭原则(对
扩展开放;对修改封闭)。
样例代码2:
public class MainTest {
public static void main(String[] args) {
Car a = new AudiFactory().getCar();
Car b = new BydFactory().getCar();
a.run();
b.run();
}
}
interface Car{
void run();
}
class Audi implements Car{
public void run() {
System.out.println("奥迪在跑");
}
}
class BYD implements Car{
public void run() {
System.out.println("比亚迪在跑");
}
}
interface Factory{
Car getCar();
}
class AudiFactory implements Factory{
public Audi getCar(){
return new Audi();
}
}
class BydFactory implements Factory{
public BYD getCar(){
return new BYD();
}
}
Java 的反射机制与配置文件的巧妙结合突破了限制——这在Spring 中完美的体现了出来。
37.排错
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
System.out.println(x);
}
public static void main(String[] args) {
new C().pX();
}
}
答案:
System.out.println(x);报错,无法编译通过
可以修改成:
System.out.println(super().x);
System.out.println(A.x);
38.排错
public class Ball {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name = name;
}
public void play() {
ball = new Ball("Football");
System.out.println(ball.getName());
}
}
interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable,
Bounceable {
Ball ball = new Ball("PingPang");
}
答案:
ball = new Ball(“Football”);//无法通过编译,ball是final声明的,不可以修改
39.样例
public class ComparableCircle extends Circle implements CompareObject{
ComparableCircle(double radius){
super(radius);
}
ComparableCircle(){
super(1);
}
@Override
public int compareTo(Object o) {
if(o!=null)
if(o instanceof ComparableCircle)
{
ComparableCircle obj=(ComparableCircle)o;
return (int) (super.getRadius()-obj.getRadius());
}
throw new RuntimeException("传入数据类型不正确!");
}
public static void main(String[] args) {
ComparableCircle obj1=new ComparableCircle();
ComparableCircle obj2=new ComparableCircle(2);
Object obj3=new Object();
System.out.println(obj1.compareTo(obj2));
System.out.println(obj2.compareTo(obj1));
System.out.println(obj2.compareTo(obj3));
}
}
public interface CompareObject {
public int compareTo(Object o);
}
public class Circle {
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public Circle(double radius) {
super();
this.radius = radius;
}
public Circle() {
super();
}
}
40.Java8中接口的新特性
除了可以定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略),具体修饰格式查看如下代码,权限修饰可以删除但不可以修改,默认权限为public.
public interface CompareA {
public static void method1() {
System.out.println("CompareA:北京");
}
public default void method2() {
System.out.println("CompareA:上海");
}
default void method3() {
System.out.println("CompareA:上海");
}
}
知识点:
1.接口中定义的静态方法,只能通过接口来调用,实现类无法调用
2.接口的实现类对象可以访问接口中的默认方法,也可以在实现类中进行重写默认方法
3.如果子类继承(实现)的父类和实现的接口中声明了同名同参数的方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法
4.如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下报错。
5.如何在子类中(或实现类)的方法中调用父类、接口中被重写的方法
41.内部类
1.Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
2.内部类分为成员内部类(静态内部类、非静态内部类) vs 局部内部类(方法内、代码块内、构造器内)
class Person{
static class Dog{}
class Bird{}
public void method() {
class AA{}
}
{
class BB{}
}
public Person() {
class CC{}
}
}
42.成员内部类
1.作为外部成员
调用外部类的结构
可以被static修饰
可以被4中不同的权限修饰
类内可以定义属性、方法、构造器
可以被final修饰,表示此类不能被构造
可以被abstrcat修饰
public class InnerClass {
public static void main(String[] args) {
Person.Dog dog=new Person.Dog() {
};
dog.show();
Person p=new Person();
Person.Bird bird=p.new Bird();
bird.sing();
bird.display("test");
}
}
class Person{
String name="person";
int age;
public void eat() {
System.out.println("要吃饭");
}
abstract static class Dog{
String name;
int age;
public void show() {
System.out.println("卡拉是条狗");
}
}
class Bird{
public String name="bird";
public Bird() {}
public void sing() {
System.out.println("我是一只小小鸟");
eat();//Person.this.eat();
}
public void display(String name) {
System.out.println(name);
System.out.println(this.name);
System.out.println(Person.this.name);
}
}
public void method() {
class AA{}
}
{
class BB{}
}
public Person() {
class CC{}
}
}
2.关注如下的3个问题:
如何实例化成员内部类的对象
Person.Dog dog=new Person.Dog() {};
dog.show();
Person p=new Person();
Person.Bird bird=p.new Bird();
bird.sing();
bird.display("test");
如何在成员内部类中区分调用外部类的结构
public void display(String name) {
System.out.println(name);
System.out.println(this.name);
System.out.println(Person.this.name);
}
开发中局部内部类的使用
public class InnerClassTest1 {
public Comparable getComparable() {
class MyComparable implements Comparable{
@Override
public int compareTo(Object o) {
return 0;
}
}
return new MyComparable();
}
}