利用抽象数据类型将数据和基于数据的操做封装在一块儿,使其构成一个不可分割的独立实体。 数据被保护在抽象数据类型的内部,尽量地隐藏内部的细节, 只保留一些对外接口使之与外部发生联系。用户无需知道对象内部的细节, 但能够经过对象对外提供的接口来访问该对象。程序员
注意:局部变量名能够和成员变量名同样,在方法中使用的时候,采用就近原则。并发
以Student类为例:分布式
public class Student { private String name; private int age; public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } Student s=new Student();
具体步骤:ide
封装:一个标准的手机类的代码及测试
手机类
public class SmartPhone { private String brand; private double price; private String color; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void call(String name){ System.out.println("打电话给"+name); } public void sendMessage(String name){ System.out.println("给"+name+"发短信"); } public void playGame(){ System.out.println("玩游戏"); } }
手机测试类1
public class SmartPhoneDemo { public static void main(String[] args) { SmartPhone sp=new SmartPhone(); sp.setBrand("IPhone"); sp.setPrice(6666); sp.setColor("白色"); System.out.println("使用"+sp.getBrand()+"牌、售价为"+sp.getPrice()+"元的" +sp.getColor()+"的手机"); sp.call("Jobs"); sp.sendMessage("Kuke"); sp.playGame(); } }
一个手机对象的内存简图:函数
手机测试类2
public class SmartPhoneDemo2 { public static void main(String[] args) { SmartPhone sp=new SmartPhone(); sp.setBrand("IPhone"); sp.setPrice(6666); sp.setColor("白色"); System.out.println("使用"+sp.getBrand()+"牌、售价为"+sp.getPrice()+"元的" +sp.getColor()+"的手机"); sp.call("Jobs"); sp.sendMessage("Kuke"); sp.playGame(); SmartPhone sp2=new SmartPhone(); sp2.setBrand("小米"); sp2.setPrice(1000); sp2.setColor("黑色"); SmartPhone sp3=sp; sp.setPrice(3555); System.out.println("使用"+sp.getBrand()+"牌、售价为"+sp.getPrice()+"元的" +sp.getColor()+"的手机"); } }
多个手机对象的内存简图:高并发
执行顺序:性能
静态代码块---构造代码块---构造方法测试
public class CodeBlock { //构造方法 CodeBlock(){ int a=10; System.out.println(a); } //构造代码块 { int a=100; System.out.println(a); } //静态代码块 static { int a=1000; System.out.println(a); } public static void main(String[] args) { CodeBlock codeBlock=new CodeBlock(); } }
输出结果:优化
1000 100 10
继承实现了 IS-A 关系,例如 Cat 和 Animal 就是一种 IS-A 关系,所以 Cat 能够继承自 Animal,从而得到 Animal 非 private 的属性和方法。this
继承应该遵循里氏替换原则,子类对象必须可以替换掉全部父类对象。
Cat 能够当作 Animal 来使用,也就是说可使用 Animal 引用 Cat 对象。父类引用指向子类对象称为 向上转型 。
Animal animal = new Cat();
在子类方法中的查找顺序:
在子类方法的局部范围找,有就使用
在子类的成员范围找,有就使用
在父类的成员范围找,有就使用
若是还找不到,就报错
缘由:由于子类会继承父类中的数据,可能还会使用父类的数据。因此,子类初始化以前, 必定要完成父类数据的初始化。
方式一:子类经过super去显示调用父类其余的带参的构造方法
方式二:子类经过this去调用本类的其余构造方法 (子类必定要有一个去访问父类的构造方法,不然父类数据就没有初始化)
/** * 1. 子类中全部的构造方法默认会都会访问父类中空参数的构造方法 * 2. 每个子类的构造方法第一条语句默认是:super() */ class Father{ public Father() { System.out.println("Father的无参构造函数"); } } class Son extends Father{ public Son() { //super(); System.out.println("Son的无参构造函数"); } public Son(String name) { //super(); System.out.println("Son的带参构造函数"); } } public class InheritanceDemo { public static void main(String[] args) { //使用无参构造函数初始化 Son son=new Son(); System.out.println("==========="); //使用带参构造函数初始化 Son son2=new Son("林青霞"); } }
输出结果:
Father的无参构造函数 Son的无参构造函数 =========== Father的无参构造函数 Son的带参构造函数 /** * 3. 若是父类中没有无参构造方法,该怎么办呢? 方式一:子类经过super去显示调用父类其余的带参的构造方法 方式二:子类经过this去调用本类的其余构造方法 (子类必定要有一个去访问父类的构造方法,不然父类数据就没有初始化) */ class Parent{ public Parent(String name){ System.out.println("Parent的带参构造函数"); } } class Child extends Parent{ public Child() { //子类经过super去显示调用父类其余的带参的构造方法 super("林青霞"); System.out.println("Child的无参构造函数"); } public Child(String name) { //方式一:子类经过super去显示调用父类其余的带参的构造方法 //super(name); //方式二:子类经过this去调用本类的其余构造方法 this();//嗲用Child()的无参构造函数 System.out.println("Child的带参构造函数"); } } public class InheritanceDemo2 { public static void main(String[] args) { Child c = new Child(); System.out.println("=============="); Child c2 = new Child("林青霞"); } }
输出结果:
Parent的带参构造函数
Child的无参构造函数
==============
Parent的带参构造函数
Child的无参构造函数
Child的带参构造函数
一个类的成员变量的初始化:
子类的初始化(分层初始化)
class X{ Y b=new Y(); //显式初始化 X(){ System.out.println("X"); } } class Y{ Y(){ System.out.println("Y"); } } public class Z extends X{ Y y=new Y(); public Z() { super();//子类的初始化(分层初始化):先进行父类的初始化,而后再进行子类的初始化。 System.out.println("Z"); } public static void main(String[] args) { new Z(); } }
输出结果:
Y
X
Y
Z
重写(Override):子类和父类中出现了如出一辙的方法声明
注意:
final关键字是最终的意思,能够修饰类,修饰变量,修饰成员方法
注意:
在方法内部,该变量不能够被改变
在方法声明上,分为基本类型和引用类型的状况
(1)基本类型:是值不能变
(2)引用类型:是地址不能变,可是该对象的堆内存中的值是能够改变的
在对象构造完毕前便可(非静态常量),被final修饰的变量只能赋值一次。
继承:一个标准的动物类、猫类、狗类的代码及测试
动物类
class Animal{ private String name; private int age; private String color; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void eat(){ System.out.print("吃什么东西?"); } }
猫类
class Cat extends Animal{ @Override public void eat() { super.eat(); System.out.println("猫粮"); } public void play(){ System.out.println("小猫在玩耍"); } }
狗类
class Dog extends Animal{ @Override public void eat() { super.eat(); System.out.println("狗粮"); } public void bark(){ System.out.println("小狗汪汪叫"); } }
测试
public class AnimalDemo { public static void main(String[] args) { Dog dog=new Dog(); dog.setName("旺财"); dog.setAge(12); dog.setColor("黄色"); System.out.println(dog.getName()+"\t"+dog.getAge()+"\t"+dog.getColor()); dog.eat(); dog.bark(); Cat cat=new Cat(); cat.setName("汤姆"); cat.setAge(12); cat.setColor("蓝色"); System.out.println(cat.getName()+"\t"+cat.getAge()+"\t"+cat.getColor()); cat.eat(); cat.play(); } }
某一个事物,在不一样时刻表现出来的不一样状态。 具体来说,就是调用同一方法,会执行不一样的功能。
实际生活:水在不一样时刻的状态。
多态分为编译时多态和运行时多态:
好处
提升了代码的维护性(由继承保证)
提升了程序的扩展性(由多态保证)
弊端
不能访问子类特有功能(特有方法)
如何访问子类中的特有功能?
/** * 对象间的转型问题: 向上转型: Parent f = new Child(); 向下转型: Child z = (Child)f; //要求该f必须是可以转换为Zi的。(父到子) */ class Parent { public void show() { System.out.println("show fu"); } } class Child extends Parent { public void show() { System.out.println("show zi"); } public void method() { System.out.println("method zi"); } } public class PolymorphismDemo { public static void main(String[] args) { Parent fu=new Child(); fu.show(); //fu.method();//不能访问子类特有功能(特有方法) Child zi=(Child)fu; //向下转型 zi.show(); zi.method(); } }
输出结果:
show zi show zi method zi class Animal { public void eat(){} } class Dog extends Animal { public void eat() {} public void lookDoor() { } } class Cat extends Animal { public void eat() { } public void playGame() { } } public class PolymorphismDemo3 { public static void main(String[] args) { //内存中的是狗 Animal a = new Dog(); Dog d = (Dog)a; //内存中是猫 a = new Cat(); Cat c = (Cat)a; //内存中是猫 Dog dd = (Dog)a; //ClassCastException } }
多态中对象内存图
/** * 多态中的成员访问特色: A:成员变量 编译看左边,运行看左边。 B:构造方法 建立子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。 C:成员方法 编译看左边,运行看右边。( 因为成员方法存在方法重写,因此它运行看右边。) D:静态方法 编译看左边,运行看左边。(静态和类相关,算不上重写,因此,访问仍是左边的) */ class Fu{ public int num=100; public void show(){ System.out.println("show function"); } public static void function(){ System.out.println("function Fu"); } } class Zi extends Fu { public int num = 1000; public int num2 = 200; @Override public void show() { System.out.println("show Zi"); } public void method() { System.out.println("method zi"); } public static void function() { System.out.println("function Zi"); } } public class PolymorphismDemo2 { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num); //System.out.println(f.num2); f.show(); //找不到符号 //f.method(); f.function(); } }
输出结果:
100 show Zi function Fu
免费Java高级资料须要本身领取,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G。
传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q