有兴趣可关注微信公众号:Java成长录
微信公众号持续更新------------部分会在csdn同步
1.面向对象
Java语言是面向对象语言,那么什么是面向对象编程(Object Oriented Programming)呢?
如果对于面向对象不是很清楚,那可以与面向过程进行比较理解。
举个买电脑的例子:
类比面向过程:
自己去问配置,问价格,问性能,最后才能买到一台整机。并且此时如果你想改变电脑的配件还需要从头问一遍,整个过程比较麻烦。
类比面向对象:
你朋友懂电脑,你只需带着你朋友去,你朋友最后帮你买到一台整机。此时你朋友就是一个对象,你只需要去操作对象就可以完成你要做的事情。此时如果你想改配置,你只需跟你朋友说一下,接着你只需等待整机就行啦!
面向过程:
优点:性能好
缺点:不易维护,不易扩展,耦合度高
面向对象:
优点:易维护,易扩展,耦合度低
缺点:相比面向过程实例化对象消耗性
面向对象的三大特性:封装,继承,多态
2.封装,继承,多态
-
封装
将数据以及对数据的操作隐藏在类的内部,外部程序只能通过对外开放的方法操作数据,一般是set()get()方法;
例如下面这个员工类Empolyee :
public class Empolyee {
private String name;
private Integer salary;
private Integer age;
public String getName() {
return name;
}
public Integer getSalary() {
return salary;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return super.toString();
}
}
类变量(静态变量):
程序执行前生成,被static修饰的变量,通过类名.变量名来获取,一般作为final来修饰作为常量来用。
成员变量:
类中声明的属性变量,随着对象生成而生成,随着对象消失而消失
局部变量:
类的方法中的变量,无修饰符,必须初始化
成员变量及方法作用域(默认default):
类内部 | 包 | 子类 | 外部包 | |
public | √ | √ | √ | √ |
protect | √ | √ | √ | |
default | √ | √ | ||
private | √ |
-
继承
类与类的一种关系,子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有)从而实现了实现代码的复用
-
Java不支持多继承,但是支持多重继承
Java继承特性:
-
子类可以继承父类非private成员
-
子类拥有父类非 private 的属性、方法。
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法,但是子类的访问级别不能低于父类确保使用父类实例的地方都能使用子类。
-
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
-
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)
Java继承关键字:
extends:继承关系关键字
super:可以调用父类成员,可以通过super调用父类构造器
-
多态
多态一般分为引用多态和方法多态
引用多态是指:父类引用可以指向本类对象,也可指向子类对象。引用多态的强大主要体现在调用属性、方法时,可以根据引用具体指向的对象去调用,例如:子类中重写了父类方法。
方法多态:子类中可以重写父类的方法,在调用方法时根据引用指向的子类对象决定调用哪个具体的方法。方法多态的强大主要体现在可以根据调用时参数的不同,而自主匹配调用的方法,例如:重载。
3.过程控制语句
-
break
for(int i = 0; i <= 3; i++){
System.out.println("i="+i);
//跳出循环
if(i == 2){
break;
}
}
遇到break则会跳出循环
输出结果:
i=0
i=1
i=2
-
continue
for(int i = 0; i <= 3; i++){
//结束当前循环重新开始下一个循环,i=2时下面的输出语句不会执行
if(i == 2){
continue;
}
System.out.println("i="+i);
}
循环过程中遇到continue结束当前循环重新开始下一个循环
输出结果:
i=0
i=1
i=3
-
switch
从 Java 7 开始,可以在 switch 条件判断语句中使用 String 对象。
switch判断条件条件不能时long型
不能使用long型的原因可能时因为,当时switch设计出来就是为了少数的值进行判断,如果值过于复杂还是用if比较方便。
String m = "a";
switch (m) {
case "a":
System.out.println("aa");
break;
case "b":
System.out.println("aa");
break;
}
4.重载&重写
重载:
Java允许任何方法被重载,包括static,只要是存在于同一个类中,一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同就叫做方法重载。
应该注意的是,返回值不同,其它都相同不算是重载
因为方法名称和方法参数被称作方法签名,返回类型不属于方法签名的一部分,而且Java中也是不允许两个方法只有返回类型不一样。
重写:
重写存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法,但是方法实现发生了变化。
为了满足里式替换原则,重写有以下三个限制:
-
子类方法的访问权限必须大于等于父类方法;
-
子类方法的返回类型必须是父类方法返回类型或为其子类型。
-
子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。
使用 @Override 注解,可以让编译器帮忙检查是否满足上面的三个限制条件。
在调用一个方法时,先从本类中查找看是否有对应的方法,如果没有查找到再到父类中查看,看是否有继承来的方法。否则就要对参数进行转型,转成父类之后看是否有对应的方法。总的来说,方法调用的优先级为:
-
this.method(this)
-
super.method(this)
-
this.method(super)
-
super.method(super)
class A {
public void show(A obj) {
System.out.println("A.show(A)");
}
public void show(C obj) {
System.out.println("A.show(C)");
}
}
class B extends A {
@Override
public void show(A obj) {
System.out.println("B.show(A)");
}
}
class C extends B {
}
class D extends C {
}
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
D d = new D();
// 在 A 中存在 show(A obj),直接调用
a.show(a); // A.show(A)
// 在 A 中不存在 show(B obj),将 B 转型成其父类 A
a.show(b); // A.show(A)
// 在 B 中存在从 A 继承来的 show(C obj),直接调用
b.show(c); // A.show(C)
// 在 B 中不存在 show(D obj),但是存在从 A 继承来的 show(C obj),将 D 转型成其父类 C
b.show(d); // A.show(C)
// 引用的还是 B 对象,所以 ba 和 b 的调用结果一样
A ba = new B();
ba.show(c); // A.show(C)
ba.show(d); // A.show(C)
}
5.抽象类与接口
抽象类最大的特点就是被abstract修饰,存在抽象方法的类一定是抽象类,抽象类与普通类最大的区别就是,抽象类不能实例化,必须继承抽象类的子类才能实例化。
抽象类可以有自己的默认的方法,但是抽象方法必须被子类实现.
public abstract class AbstractClass{
public void method1(){
System.out.println("method1");
}
public abstract void method2();
public static void main( String[] args )
}
class B extends AbstractClass{
@Override
public void method2() {
}
}
接口是抽象方法的集合,接口只能继承父接口,接口中常量必须是
public static类型,如果类实现一个接口不实现全部方法,这个类一定是抽象类。
比较:
-
从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。
-
接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。
-
接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。
抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问权限可以是任意的,但接口中定义的变量只能是 public static final 类型的,并且默认即为 public static final 类型。
使用比较
使用接口:
-
需要让不相关的类都实现一个方法
-
需要使用多重继承。
使用抽象类:
-
需要在几个相关的类中共享代码。
-
需要能控制继承来的成员的访问权限,而不是都为 public。
-
需要继承非静态和非常量字段。
6.匿名内部类
匿名内部类就是没有名字的类,因为没有名字只能用一次,匿名内部类必须继承一个类或实现一个接口。
public abstract class Father{
public abstract void method2();
}
class Child extends Father{
@Override
public void method() {
System.out.println("实现方法");
}
}
如果Child只用一次,那就可以使用匿名内部类
Fathera = new Father() {
@Override
public void method() {
System.out.println("实现方法");
}
};
8.代码块
静态代码块>构造函数>普通代码块
静态代码块
要求: 不能存在任何方法里
格式:
static{
System.out.println("静态代码块");
}
执行时机时间:类加载时候静态代码块就被加载啦
普通代码块
要求:在方法中
格式:
{
System.out.println("普通代码块");
}
执行时机:按照书写顺序