Java基础面向对象复习–day04

知识和问题整理

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();
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值