20145330《Java程序设计》第四周学习总结

20145330《Java程序设计》第四周学习总结

一周两章新知识的自学与理解真的是很考验和锻炼我们,也对前面几章我们的学习进行了检测,遇到忘记和不懂的知识就再复习前面的,如此巩固也让我对之前的知识更深刻的理解了。

继承与多态

  • 继承基本上就是避免多个类间重复定义共同行为

		public class SwordsMan extends Role{
   		  public void fight(){
        	System.out.println("挥剑攻击");
    		}
		}
 这里看到新的关键词extends,表示会继承Role的行为,并定义fight()方法的程序代码

		public class RPG {
    		public static void main(String[] args) {
        		demoSwordsMan();
       			demoMagician();
   		 }

   		 static void demoSwordsMan(){
        	SwordsMan swordsMan=new SwordsMan();
        	swordsMan.setName("Justin");
        	swordsMan.setLevel(1);
        	swordsMan.setBlood(200);
        		System.out.printf("剑士:(%s,%d,%d)%n",swordsMan.getName(),
              	  swordsMan.getLevel(),swordsMan.getBlood());
   			 }
		}

- 虽然`SwordsMan`与`Magician`并没有定义`getName()`、`getLevel()`、`getBlood()`等方法,但从`Role`中继承了这些方法,所以就可以直接使用。
- 执行结果如下:
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160327215825948-1607289495.png)



- 在java中,子类只能继承一个父类
- 子类与父类间会有ISA关系
	- 例如之前 `SwordsMan`继承了`Role`,所以`SwordsMan`是一种`Role` 
- 如果例子中游戏角色增多,一直重载会很麻烦,若所有角色都继承`role`

	public class RPG2 {
		public static void main(String[] args) {

   			 SwordsMan swordsMan = new SwordsMan();
   			 swordsMan.setName("Justin");
   			 swordsMan.setLevel(1);
   			 swordsMan.setBlood(200);

    		 Magician magician = new Magician();
  			 magician.setName("Monica");
    		 magician.setLevel(1);
    		 magician.setBlood(100);

    			showBlood(swordsMan);
    			showBlood(magician);
				 }

			static void showBlood(Role role) {
	 System.out.printf("%s 血量 %d%n",role.getName(),role.getBlood());
		}
	}

![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160326160515323-1069362983.png)
这样写的好处就是就算有100种角色,只要他们都继承`role`就可以用这种方法显示血量,而不用像之前重载的方式
- 多态以抽象方式解释,就是使用单一接口操作多种类型对象。若用范例解释:在`showblood`方法中,既可以通过`role`类型操作`swordsman`,也可以通过`role`类型操作`magician`对象
- 继承可以复用代码,更大的用处是实现「多态」
- 封装是继承的基础,继承是多态的基础
- 在继承父类后,定义与父类中相同的方法部署,但执行内容不同,这称为重新定义

- 继承语法细节
	- `public/package/protected/private` 
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160326163233808-797037595.png)
被声明为`protected`的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类里直接存取。

- 垃圾收集
	- 无法通过变量引用的对象就是GC认定的垃圾对象
	- 垃圾回收前会调用finalize()方法,但由于调用时机无法确定,建议不要使用finalize()方法

   public class Magician extends Role{
	...
	@Override
	   public String toString(){
	   return"魔法师"+super.toString();
		   }
		}
可以使用`super`关键词调用的父类方法,不能定义为`private`

- 重新定义方法要注意,对于父类中的方法权限,只能扩大不能缩小,若原来成员`public`,子类中重新定义时不可为`private`或`protected`
- 构造函数可以重载,父类中可重载多个构造函数,如果子类构造函数中没有指定执行父类中那个构造函数,默认会调用父类中无参数的构造函数
- 如果指定变量值之后,就不想再改变变量值,可以在声明变量时加上`final`限定,如果后续写程序时,想修改`final`变量,就会出现编译错误
- `class`前也可以加上`final`关键字,如果`class`前使用了`final`关键字定义,那么表示这个类是最后一个了,不会再有子类,也就是不能被继承。   
- 以下是几个典型代码
	public abstract class GuessGame {
	 public void go(){

    int number = (int) (Math.random()*10);
    int guess;        
	do {
        print("输入数字'");
        guess = nextInt();
        
    } while(guess != number);
    println("猜中啦");
           
	 }

	 public  void println(String text){
   	 print(text + "\n");
    
	}
	 public abstract void print(String text);
	 public abstract int nextInt();
          
	}

	import java.util.Scanner;

	public class ConsoleGame extends  GuessGame {

 	private  Scanner scanner = new Scanner(System.in);

 	@Override
 	public void print(String text){
    System.out.print(text);
	  }
	 @Override
	public void println(String text){
    System.out.println(text);

	}
	@Override
	public int nextlnt() {
    return scanner.nextlnt();
	}
	}

		public class Guess { 
		public static void main(String[] args) 
		{ 
		GuessGame game = new ConsoleGame();	
 		game.go(); 
		} 
		}
```
```
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160327203213308-857314392.png)

###接口与多态###
- 对于定义行为,可以使用`interface`关键字定义,接口中的方法不能操作,直接标示为`abstract`,而且一定是`public`。
- 类要操作接口,必须使用`implements`关键字
- 类可以操作两个以上的类,也就是拥有两种以上的行为。
- 使用`interface`来定义抽象的行为外观,方法声明为`public abstract`,无需且不能有操作
- 接口也以继承别的接口,也可以继承两个以上的接口,同样也使用`extends`关键字,这代表了继承父接口的行为
- 类要操作接口,必须使用`implements`关键字
```
```

		public class Human implements Swimmer{
    	private String name;
    	public Human(String name){
        this.name=name;
    	}
   		 public String getName(){
   		     return name;
    	}
    	@Override
    	public void swim() {
        System.out.printf("人类%s游泳%n",name);
   		 }
		}
```
```

		public class Submarine implements Swimmer {

  		private String name;

    	public Submarine(String name) {
        this.name = name;
   		 }

   		 public String getName() {
        return name;
    	}

   		 @Override
    	public void swim() {
   	     System.out.printf("潜水艇%s潜行%n", name);
   		 }
		}
```
```

		public class Ocean {

   		public static void main(String[] args) {
        doSwim(new Human("贾斯汀"));
        doSwim(new Submarine("黄色一号"));
   		 }

    	static void doSwim(Swimmer swimmer){
        swimmer.swim();
   		 }
			}
```
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160327204956495-1867513131.png)

- 多态语法的判断:判断“右边是不是拥有左边的行为”或者“右边对象是不是操作了左边接口”
- 只要操作接口对象一直,都可以使用doSwim的方法,提高了系统的可维护性。
- 范例如下
```

		public class Ocean {
    	public static void main(String[] args) {
        doSwim(new Ugly("尼莫"));
        doSwim(new Shark("兰尼"));
        doSwim(new Human("贾斯汀"));
        doSwim(new Submarine("黄色一号"));

    	}

    	static void doSwim(Swimmer swimmer){
        swimmer.swim();
    	}
		}
```
- 定义Seaplane操作Swimmer与Flyer接口;类可以继承,并能操作某些接口,因此它即能飞又能又能游;
```

		public class Seaplane implements Swimmer,Flyer {
    	private String name;
   		 public Seaplane(String name){
        this.name = name;
   		 }
    	@Override
    	public void fly(){
        System.out.printf("海上飞机   %s  在飞  %n",name);

    	}
    	@Override
    	public void swim(){
        System.out.printf("海上飞机%s  航行海绵%n",name);
    	}
		}

```

- 接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为
- 接口中的方法没有操作时,必须是公开且抽象的
- 枚举常数范例:
```

	public interface Action {
   	    public static final int STOP = 0;
    	public static final int RIGHT = 1;
    	public static final int LIFT = 2;
    	public static final int UP = 3;
    	public static final int DOWN = 4;
		}
```

- 在枚举常数时要使用“=”指定值,否则会编译出错。
- Some与Other定义的execute()
	- 表示不同行为,Service有两个不同的操作方法,Some与Other在名称上有所不同。
	- 表示相同行为,可以定义一个父接口,当定义execute()方法,而some与other继承该接口,各自定义自己的doSome()与doOther()方法。
###教材中遇到的问题和解决过程###
整个的学习过程都是抽象的过程,很多概念和注意事项读过好几遍但如果没有完全理解的话,就会十分陌生,后面也看不明白,所以一定要弄清楚每一个细节和知识点。比如这次很多程序都是有子类父类的,如果没有理解知识,就不明白为什么运行不出来或者出错,通过多次反复学习,终于有了一些理解,可能还需要日积月累的联系。
###代码托管截屏###
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160327214334886-524527187.png)
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160327214352401-1176506201.png)
![](http://images2015.cnblogs.com/blog/886442/201603/886442-20160327214410261-1506869375.png)
###学习进度条###
|             | 代码行数(新增/累积)| 博客量(新增/累积)|学习时间(新增/累积)|重要成长|
| --------    | :----------------:   |:----------------:  |:---------------:    |:-----: |
| 目标        | 5000行               |   30篇             | 400小时             |        |
| 第一周      | 200/200              |   2/2              | 20/20               |        |
| 第二周      | 300/500              |   2/4              | 18/38               |        |
| 第三周      | 500/1000             |   3/7              | 22/60               |        |
| 第四周      | 300/1300             |   2/9              | 30/90               |        |

###参考资料###
- 《Java学习笔记》
posted @ 2016-03-27 21:54  20145330孙文馨  阅读(186)  评论(6编辑  收藏  举报