是因为菱形继承的问题。
解释:
两个父类继承自同一个基类,两个父类里有一个相同的方法,那么作为子类应该怎么继承这个方法?父类1的还是父类2的?但是实现多个接口则没问题,因为不管哪个接口,调用的都是同一个实现。
• 单一职责原则
– 一个类,最好只做一件事。
• 开放封闭原则
– 软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修
改封闭的。
• 接口隔离原则
– 接口应该是内聚的,一个类对另外一个类的依赖应该建立在最小的接口
上。
• 替换原则
– 子类必须能够替换其基类。
成员变量被声明时,JAVA解释器会为该属性指定默认值!
byte-short-int-long -float-double
char-int-long -float-double
show(int a ,int b,int c) //1
show(int a ,int b,double c) //2
show(int a ,double b,double c)//3
show(double a,double b,int c) //4
下面是调用
show(1,2,3);//1,2,3,4都是可行方法所有参数完全匹配1
show(1.0,2.0,3.0);//没有一个可行方法
show(1.0,2,3);//4是最佳可行方法
show(1,2.0,3);//3,4都是可行方法,没有最佳可行方法,报错
在java中主要存在4块内存空间,这些内存的名称及作用如下:
栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
堆内存空间:保存每个对象的具体属性内容。
全局数据区:保存static类型的属性。
全局代码区:保存所有的方法定义。
标称这个类成员为所有对象所共享,如果是Static变量,则就是一个全局变量,当被一个对象修改时(或者通过类名.对象名形式),这个类的全部对象看到的这个变量都已经得到了修改,实现机制是把全局变量放在JAVA内存的全局数据区。
标称这个类不能有子类。
标称这个方法不能被子类覆写。
标称这个变量为常量,不可更改。
JAVA中一切对象,内部类不过是一个绑定在外部类中的一个对象而已,比绑定在外部类的方法复杂了一点点而已。
既然是个类,那它就可以有类的一切,既然是放在一个类的内部,那么它和其他外部类的方法一样,可以访问外部类的成员。然而内部类和普通方法最大的不同是拥有成员变量,当外部类要访问这些成员变量时只需要在方法体中创建内部类的对象,且可以访问其私有成员! 看到内部类的威力了吧,可以访问私有成员!
public class InnerClassTest {
public static void main(String args[]) {
System.out.println("Start_test");
Outter ou = new Outter();
ou.do_outer();
}
}
class Outter {
private int attr1 = 1;
public Outter() {
System.out.print("Outer Construct\n");
}
class Inner {
private int attr_o= attr1;
public Inner() {
System.out.print("Inner Construct\n");
}
private void get_attr1(){
System.out.println("Inner-get-attr1\t"+attr1);
}
}
public void do_outer(){
Inner in = new Inner();
in.get_attr1();
System.out.println("Inner private attr_o\t"+in.attr_o);
}
}
回到标题1的菱形继承问题,我这个子类需要继承两个有同样基类的抽象类是吧?我用两个内部类来搞定这个事情!
看代码:
package com.chinahadoop.app;
/**
* Created by Hagrid on 2016/4/13.
*/
public class InnerClassTest {
public static void main(String args[]) {
System.out.println("Start_test");
Child child = new Child();
child.think();
}
}
abstract class GrandFather {
public GrandFather() {
System.out.println("GrandFather inited");
}
public abstract void fun();
public abstract void think();
}
abstract class Father extends GrandFather{
public Father(){
System.out.println("Father init");
}
@Override
public void fun() {
System.out.println("Father like Dog!");
}
}
abstract class Uncle extends GrandFather{
public Uncle(){
System.out.println("Uncle init!");
}
@Override
public void fun() {
System.out.println("Uncle like Cat!");
}
}
class Child extends GrandFather{
private Father father = new Father();
private Uncle uncle = new Uncle();
public Child(){
System.out.println("Child init");
}
@Override
public void fun() {
System.out.print("My Father tell me:\t");
father.fun();
System.out.print("My Uncle tell me:\t");
uncle.fun();
}
@Override
public void think() {
System.out.print("So, here is Father and Uncle in my Head: \n");
father.think();
uncle.think();
}
class Father extends com.chinahadoop.app.Father{
public Father(){
super();
}
@Override
public void think() {
System.out.println("I think my Father like Dog!");
}
}
class Uncle extends com.chinahadoop.app.Uncle{
public Uncle(){
super();
}
@Override
public void think() {
System.out.println("I think my Uncle like Cat!");
}
}
}
运行结果如下:
Start_test
GrandFather inited
GrandFather inited
Father init
GrandFather inited
Uncle init!
Child init
So, here is Father and Uncle in my Head:
I think my Father like Dog!
I think my Uncle like Cat!
假如要执行的任务需要一个对象,但却不值得创建全新的对象(原因可能 是所需的类过于简单,或是由于他只在一个方法内部使用),匿名类就显得很有用。
个人觉得匿名类在写法上更简单而已,并没有特别的用处,需要记住这种语法.
interface pr {
void print1();
}
public class noNameClass {
public pr dest() {
return new pr() {
public void print1() {
System.out.println("Hello world!!");
}
};
}
}
public static void main(String args[]) {
noNameClass c = new noNameClass();
pr hw = c.dest();
hw.print1();
}
答:抽象类表达的是is a 的语义,而接口表达的是like a 语义
在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是 这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一 个具体的对象,这样的类就是抽象类。
abstract class在Java语言中表示的是一种继承关系,一个类只能使用一次继承 关系。但是,一个类却可以实现多个interface。
假设某个abstract class中有很多子类,这个个abstract class中已经实现的方法就可以被其所有子类见到,如果我们要修改abstract class中已经实现某个方法,那么其子类的这个方法也得到了修改!但是根据开闭原则,我们禁止其修改方法,我们可以向其中添加新方法,这样其所有子类就都可以用这个新方法的实现了!!
而对于Interface的实现类,我们要实现其所有方法,如果我们想为这些子类添加一个共同的方法,那么就需要在每个实现类中添加!!
经典的门和防盗门的案例:
abstract class Door {
abstract void open();
abstract void close();
}
interface Alarm {
void alarm();
}
class AlarmDoor extends Door implements Alarm {
void open() { … }
void close() { … }
void alarm() { … }
}
10.1 一个接口就是一个模式,表达like a 语义,定义了属于这个模式的类必须具有的特性。
首先我这个接口的成员变量是常量! 你声明还是不声明都是public static final 类型的常量!这个语义是很强的,没有任何商量的余地,你要实现我这个接口,必须先全盘接收我定义的常量!
10.2 接口中的方法全部为抽象方法,因此,所有子类必须全部实现,除非你本身是接口或者抽象类!
这又是一个很强的定义,我这个接口定义的行为你必须全盘接收!
答:可以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。
可以继承。其实从Object就是个实体类,java的API文档里,每个抽象类的条目里都明确写着直接或间接继承自Object,所以这点是没有疑问的。