整体上是封装、继承、多态、抽象。
首先面向对象是一种思想。在java中万事万物皆对象。类是对相同事物的一种抽象、是不可见的,对象具体的、可见的。由对象到类的过程是抽象的过程,由类到对象的过程是实例化的过程。面向对象的三大特征分别是封装、继承和多态。
封装隐藏了类的内部实现机制,对外界而言它的内部细节是隐藏的,暴露给外界的只是它的访问方法。例如在属性的修饰符上我们往往用的private私有的,这样其它类要想访问就通过get和set方法。因此封装可以程序员按照既定的方式调用方法,不必关心方法的内部实现,便于使用; 便于修改,增强 代码的可维护性。
继承在本质上是特殊~一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。比如从猫类、狗类中可以抽象出一个动物类,具有和猫、狗、虎类的共同特性(吃、跑、叫等)。通过extends关键字来实现继承。Java中的继承是单继承,即一个子类只允许有一个父类。
Java多态是指的是首先两个类有继承关系,其次子类重写了父类的方法,最后父类引用指向子类对象。如Animal a=new Dog();这行代码就体现了多态。
Java中的多态靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程 序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存 里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
名字与类名相同;
没有返回值,但不能用void声明构造函数;
生成类的对象时自动执行,无需调用。
构造器不能被继承,因此不能被重写,但可以被重载。
super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一 个父类。
super也有三种用法:
1.普通的直接引用
与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。
2.子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
class Person{
protected String name;
public Person(String name){
this.name = name;
}
}
class StudentextendsPerson{
private String name;
publicStudent(String name, String name1){
super(name);
this.name = name1;
}
public void getInfo(){
System.out.println(this.name);
System.out.println(super.name);
}
}
public class Test{
public static void main(String[] args){
Student s1 = new Student("Father", "Child");
s1.getInfo();
}
}
3.引用父类构造函数
super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
super:它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员
数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名 (实参)
this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
super()和this()区别是
[1]super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
[2]super()和this()均需放在构造方法内第一行。尽管可以用this调用一个构造器,但却不能调用两个。
[3]this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语 句,就失去了语句的意义,编译器也不会通过。
[4]this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变
量,static方法,static语句块。从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
方法的重载和重写本质都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态。
方法重载的规则:
1)方法名一致,
2)参数列表不同(参数顺序不同或者参数类型不同或者参数个数不同)。
3)重载与方法的返回值无关,这个很关键。
方法重写的规则:
1)参数列表和返回值类型必须完全与父类的方法一致
2)构造方法不能被重写,声明为 final 的方法不能被重写,声明为 static 的方法不能被重写,但是能够被再次声明。
3)访问权限不能比父类中被重写的方法的访问权限更低。
4)重写的方法能够抛出任何检查异常(编译时异常),但是重写的方法不能抛出比被重写方法声明的更广泛的运行时异常。
1)接口中的所有方法都是抽象的,而抽象类可以有抽象方法,也可以有实例方法。
2)类需要继承,接口需要实现。一个类可以实现多个接口,但只能继承一个父类但接口却可以继承多接口。
3)接口与实现它的类不构成继承体系,即接口不是类体系的一部分。因此,不相关的类也可以实现相同的接口,而抽象类是属于类的继承体系,并且一般位于类体系的顶层。
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承具体类,但前提是具体类必须有明确的构造函数。
值传递是指在调用函数时将实际参数复制一份到函数中,这样的话如果函数对其传递过来的形式参数进行修改,将不会影响到实际参数。
引用传递是指在调用函数时将对象的地址直接传递到函数中,如果在对形式参数进行修改,将影响到实际参数的值。
equals 和== 最大的区别是一个是方法一个是运算符。
1)基本类型中,==比较的是数值是否相等。equals方法是不能用于基本数据类型数据比较的,因为基本数据类型压根就没有方法。
2)引用类型中,==比较的是对象的地址值是否相等。equals方法比较的是引用类型的变量所指向的对象的地址是否相等。应为String这个类重写了equals方法,比较的是字符串的内容。
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码 的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就 意味着Java中的任何类都包含有hashCode()函数。
在Java中,每个对象都可以调用自己的hashCode方法得到自己的哈希值(hashCode),相当于对象的指纹信息,通常说世界上没有完全一样的指纹,但是在Java中没有这么绝对,我们依然可以用hashCode值来做一些提前的判断。
1)如果两个对象的hashCode值不一样,那么他们肯定是不同的两个对象;
2)如果两个对象的hashCode值一样,也不代表就是同一个对象;
3)如果两个对象的equals方法相等,那么他们的hashCode值一定相等。
在Java的一些集合类的实现中,在比较两个对象的值是否相等的时候,会根据上面的基本原则,先调用对象的hashCode值来进行比较,如果hashCode值不一样,就可以认定这是两个不一样的数据,如果hashCode值相同,我们会进一步调用equals()方法进行内容的比较。
equals 方法是用来比较对象大小是否相等的方法,hashcode 方法是用来判断每个对象 hash 值的一种方法。如果只重写 equals 方法而不重写 hashcode 方法,很可能会造成两个不同的对象,它们的 hashcode 也相等,造成冲突。
例如:String str1 = "通话"; String str2 = "重地";
它们两个的 hashcode 相等,但是 equals 可不相等。
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。
Java对于eqauls方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
(2)如果两个对象的hashCode相同,它们并不一定相同。
当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对 象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如 果哈希码频繁的冲突将会造成存取性能急剧下降)。
都不能。
1)抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。
2)本地方法是由本地代码(如 C++ 代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。
3)synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
修饰类:当用final修饰一个类时,表明这个类不能被继承。正如String类是不能被继承的。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
修饰方法:使用final修饰方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。因此,只有在想明确禁止该方法在子类中被覆盖的情况下才将方法设置为final。(注:一个类中的private方法会隐式地被指定为final方法)
修饰变量:对于被final修饰的变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。虽然不能再指向其他对象,但是它指向的对象的内容是可变的。
public class Demo1 {
public static void main(String[] args) {
MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();
System.out.println(myClass1.i);
System.out.println(myClass2.i);
System.out.println(myClass1.j);
System.out.println(myClass2.j);
}
}
class MyClass {
public final double i = Math.random();
public static double j = Math.random();
}
运行结果:
0.3222977275463088
0.2565532218939688
0.36856868882926397
0.36856868882926397
每次打印的两个j值都是一样的,而i的值却是不同的。从这里就可以知道final和static变量的区别了。static属于类级别的不可变,而final是对象级别的不可变。
1)final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,被其修饰的类不可继承。
2)finally:异常处理语句结构的一部分,表示总是执行。
3)finalize:Object 类的一个方法,当java对象没有更多的引用指向的时候,系统会自动的由垃圾回收器来负责调用此方法进行回收前的准备工作和垃圾回收。
静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的 加载过程中,JVM只为静态变量分配一次内存空间。
实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象 的,在内存中,创建几次对象,就有几份成员变量。
静态方法和实例方法的区别主要体现在两个方面:
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的 方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法), 而不允许访问实例成员变量和实例方法;实例方法则无此限制。
class A{
static{
System.out.print("1");
}
public A(){
System.out.print("2");
}
}
class B extends A{
static{
System.out.print("a");
}
public B(){
System.out.print("b");
}
}
public class Hello{
public static void main(String[] ars){
A ab = new B(); //执行到此处,结果: 1a2b
ab = new B(); //执行到此处,结果: 1a2b2b
}
}
输出结果为 1a2b2b;修饰符 | 当前类 | 同包 | 子类 | 其它包 |
---|---|---|---|---|
public | 是 | 是 | 是 | 是 |
protected | 是 | 是 | 是 | 否 |
默认(缺省) | 是 | 是 | 否 | 否 |
private | 是 | 否 | 否 | 否 |
类的成员不写访问修饰时默认为default。默认对于同一个包中的其他类相当于公开 (public),对于不是同一个包中的其他类相当于私有(private)。受保护(protected)对 子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。Java中,外部类的修饰符 只能是public或默认,类的成员(包括内部类)的修饰符可以是以上四种。
goto 是Java中的保留字,在目前版本的Java中没有使用。(根据James Gosling(Java之 父)编写的《The Java Programming Language》一书的附录中给出了一个Java关键字列 表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保 留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库 中使用过的有特殊意义的单词或单词的组合都被视为保留字)
由于 Java 不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是 public.一个类可以实现多个接口。