# 习题
# 值传递习题1
public class TransferTest {
public static void main(String args[]) {
TransferTest test = new TransferTest();
test.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);// 20
}
public void second(Value v, int i) {
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println(v.i + " " + i);// 15,0
}
}
class Value {
int i = 15;
}
# 非值传递习题
public class Test {
public static void main(String[] args){
int a = 10;
int b = 10;
method(a,b);// 需要在method方法被调用后,仅打印出a=100,b=200,完成method的编码
System.out.println("a=" + a);
System.out.println("b=" + b);
}
// 方法编写处
// 方法1。直接输出并exit
public static void method(int a,int b){
System.out.println("a=" + a*10);
System.out.println("b=" + b*20);
System.exit(0);
}
// 方法2,重写打印流
private static void method(int a, int b) {
PrintStream printStream = new PrintStream(System.out){
@Override
public void println(String s) {
if ("a=10".equals(s)){
s = "a=100";
} else if ("b=10".equals(s)){
s = "b=200";
}
super.println(s);
}
};
System.setOut(printStream);
}
}
# 递归简单练习
public int sum(int num){
if(num == 1){
return 1;
}
else{
return num + sum(num - 1);
}
}
// 计算1-n之间所有自然数的乘积:n!
public int getSum1(int n) {
if (n == 1) {
return 1;
} else {
return n * getSum1(n - 1);
}
}
// 已知有一个数列:f(0) = 1,f(1) = 4, f(n+2)=2*f(n+1) + f(n),其中n是大于0的整数,求f(10)的值。
public int f(int n){
if(n == 0){
return 1;
}else if(n == 1){
return 4;
}else{
return 2*f(n - 1) + f(n - 2);
}
}
// 已知一个数列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值。
public static int m1(int num){
if (num==21){
return 4;
} else if (num == 20){
return 1;
} else {
return m1(num+2)-2*m1(num+1);
}
}
# 递归练习
// 递归调用的次数?若k为10,则?
private static int count = 0;
public static int recursion(int k) {
count++;
System.out.println("count:"+count+" k:"+k);
if (k<=0){
return 0;
}
return recursion(k-1) + recursion(k-2);
}
# 斐波那契数列
// 输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值 1 1 2 3 5 8 13 21 34 55
# 汉诺塔
递归
# 快排
递归
# 多态练习1
public class FieldMethodTest {
public static void main(String[] args) {
Sub s = new Sub();
System.out.println(s.count);//20
s.display();//20
Base b = s;//多态性
System.out.println(b == s);//true
System.out.println(b.count);//10
b.display();//20
}
}
class Base {
int count = 10;
public void display() {
System.out.println(this.count);
}
}
class Sub extends Base {
int count = 20;
public void display() {
System.out.println(this.count);
}
}
# 多态练习—可变参数重写
public class InterviewTest1 {
public static void main(String[] args) {
Base1 base = new Sub1();
base.add(1, 2, 3);// 此处父类引用调用方法,此方法被重写了,所以结果为sub_1
Sub1 s = (Sub1) base;
s.add(1, 2, 3);// 此处子类引用调用方法,直接调用确定的方法,所以结果为sub_2
}
}
class Base1 {
public void add(int a, int... arr) {
System.out.println("base1");
}
}
class Sub1 extends Base1 {
// @Override //就是重写了
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
// 不是这个方法重写父类!!!
public void add(int a, int b, int c) {
System.out.println("sub_2");
}
}
# 如何证明多态是运行时绑定的?
class Animal {
protected void eat() {
System.out.println("animal eat food");
}
}
class Cat extends Animal {
protected void eat() {
System.out.println("cat eat fish");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("Dog eat bone");
}
}
class Sheep extends Animal {
public void eat() {
System.out.println("Sheep eat grass");
}
}
public class InterviewTest {
public static Animal getInstance(int key) {
switch (key) {
case 0:
return new Cat ();
case 1:
return new Dog ();
default:
return new Sheep ();
}
}
public static void main(String[] args) {
int key = new Random().nextInt(3);
System.out.println(key);
Animal animal = getInstance(key);
animal.eat();
}
}
# 接口、抽象类问题1
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
// 编译不通过,因为x不明确。可以写super.x 和 A.x来调用类中和接口中的x
System.out.println(x);
//
}
public static void main(String[] args) {
new C().pX();
}
}
# 接口、抽象类问题2
interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable,Bounceable {
Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name = name;
}
public void play() {
// 接口中已定义了该常量,且默认为public static final,此处重新赋值则编译报错
ball = new Ball("Football");
System.out.println(ball.getName());
}
}
# 接口和抽象类的对比
| No. | 区别点 | 抽象类 | 接口 |
|---|---|---|---|
| 1 | 定义 | 包含抽象方法的类 | 主要是抽象方法和全局常量的集合 ` |
| 2 | 组成 | 构造方法、抽象方法、普通方法、 常量、变量 | 常量、抽象方法、(jdk8.0:默认方法、静态方法) |
| 3 | 使用 | 子类继承抽象类(extends) | 子类实现接口(implements) |
| 4 | 关系 | 抽象类可以实现多个接口 | 接口不能继承抽象类,但允许继承多个接口 |
| 5 | 常见设计模式 | 模板方法 | 简单工厂、工厂方法、代理模式 |
| 6 | 对象 | 都通过对象的多态性产生实例化对象 | |
| 7 | 局限 | 抽象类有单继承的局限 | 接口没有此局限 |
| 8 | 实际 | 作为一个模板 | 是作为一个标准或是表示一种能力 |
| 9 | 选择 | 如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限 |
# 定义一个类的时候,权限修饰符规则
外部类:public / (default)
成员内部类:public / protected / (default) / private
局部内部类:什么都不能写
public class Demo { public static void main(String[] args) { new Demo(){ //匿名对象,匿名内部类 void show(){ System.out.println("hello"); } }.show();//hello //若是给对象起名,并用该名调用show方法,则编译不通过,因为父类中没有此方法,当前所属方法才能使用它 } }