大数据学习20190321
面向对象的四大特性
static关键字
用于修饰成员变量和成员方法;
static的特点:
-被所有的对象所共享;
-可以使用类名调用;
-静态的加载优先于对象;
-随着类的加载而加载。
static的注意事项
-静态方法只能访问静态成员;
-非静态方法既能访问静态也可以访问非静态;
-非静态方法中不可以定义静态变量;
-静态方法中不可以定义this、super关键字。
static的优点:
-对对象的共享数据提供单独空间的存储,节省空间,没有必要每一个对象都单独存储一份。
-可以直接被类名调用,不用在堆内存创建对象。
static的弊端:
-访问出现局限性。(静态虽好,但只能访问静态)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class MathDemo { public static void main(String[] args) { // Math:包含了一些基本的数学运算方法 System.out.println(Math.E); // 自然对数 System.out.println(Math.PI); // 圆周率 System.out.println(Math.abs(-12)); // 返回绝对值 // Math.ceil(double a):向上取整 System.out.println(Math.ceil(3.1)); // 4.0 // Math.floor(double a):向下取整 System.out.println(Math.floor(3.9)); // 3.0 // Math.round(double a):四舍五入 System.out.println(Math.round(3.4)); // 3 System.out.println(Math.round(3.6)); // 4 // Math.pow(double a,double b):返回a的b次幂; System.out.println(Math.pow(2, 3)); // 8.0 // Math.round():返回一个[0,1)之间的随机数。 } }
自定义工具类
构造方法私有。
代码块
在Java中,使用{}括起来的代码被称为代码块。
代码块分类
-局部代码块:在方法内;用{}括起来,控制变量的生命周期(作用域)。
-构造代码块:提取构造方法中的共性,只要创建对象,构造代码块就会执行;并且在构造方法执行之前执行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo; public class Test01 { public static void main(String[] args) { Teacher t1 = new Teacher(); System.out.println("------------------------------"); Teacher t2 = new Teacher("nike",10); } } class Teacher { String name; int age; // 构造代码块 { for (int i = 0; i < 10; i++) { System.out.println("我爱Java"); } } public Teacher() { } public Teacher(String name, int age) { this.name = name; this.age = age; } }
-静态代码块:随着类的加载而加载,只加载一次。加载类时需要做的一些初始化,比如加载驱动。
public class Blocktest { static { System.out.println("BlockTest静态代码块执行"); } { System.out.println("BlockTest构造代码块执行"); } public Blocktest() { System.out.println("Blocktest无参空构造执行"); } public static void main(String[] args) { System.out.println("BLockTest的主函数执行了"); Coder coder = new Coder(); Coder coder1 = new Coder(); } } class Coder { static { System.out.println("Coder静态代码块执行"); } { System.out.println("Coder构造代码块执行"); } public Coder() { System.out.println("Coder无参构造方法执行"); } } // BlockTest静态代码块执行 // BLockTest的主函数执行了 // Coder静态代码块执行 // Coder构造代码块执行 // Coder无参构造方法执行 // Coder构造代码块执行 // Coder无参构造方法执行
-同步代码块
/* * static关键字: * 静态的属性和方法属于类的,使用的时候使用类名.属性名或方法名; * 非静态的属性和方法属于对象的,使用的时候需要先实例化对象(new),然后使用对象.属性名或方法名; * 非静态属性在当前类中不能静态的方法直接使用; * 静态方法和属性在当前类中可以被静态和非静态方法直接使用; * * 在Java中static修饰的函数不能被子类重写; * 被final修饰的父类函数是无法被重写; * 被private修饰的父类函数无法被继承。 * * 静态代码块: * static{Java代码块} * 静态代码块在类被第一次加载的时候第一个执行,并且只执行一次; * */
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class StaticDemo { String a = "非静态属性"; static String b = "静态属性"; static int c; static int d; static { System.out.println("这是静态代码块,在类第一次被加载的时候第一个被执行"); c = 5; d = 4; } public static void staticMethod() { System.out.println("这是静态方法!"); // System.out.println(a); //静态方法无法直接调用非静态属性 System.out.println(b); } public void unStaticMethod() { System.out.println("这是非静态方法!"); System.out.println(a); System.out.println(b); } public static void main(String[] args) { staticMethod(); // System.out.println(b); // unStaticMethod(); // System.out.println(a); System.out.println(b); StaticDemo sd = new StaticDemo(); System.out.println(sd.a); System.out.println(sd.b); } }
抽象
把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来的一般叫类或者接口,抽象并不打算了解全部问题,而是选择其中一部分,暂时不用部分细节。
抽象包括两个方面:一个是数据抽象,而是过程抽象。
数据抽象:表示世界中一类事物的特征,就是对象的属性;
过程抽象:表示世界中一类事物的行为,就是对象的行为。
封装
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo; public class Teacher { //对属性私有化进行封装 赋值方法 取值方法 //没有私有化的属性也可以进行封装,但没有意义 private double money = 100; public void setMoney(double money){ this.money = money; } public double getMoney(){ return money; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo; public class Student { public static void main(String[] args) { Teacher t1 = new Teacher(); // System.out.println(t1.money); System.out.println(t1.getMoney()); t1.setMoney(200); System.out.println(t1.getMoney()); } }
1.通过构造方法创建对象
Student stu = new Student();
2.通过工具类(媒婆)创建对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo; public class OopDemo01 { static OopDemo od = new OopDemo(); public static OopDemo getInstance(){ return od; } }
3.通过工厂模式(代理模式)创建对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo; public class FactoryDemo { OopDemo od; public static OopDemo getOopDemo(){ return new OopDemo(); } public OopDemo getOopDemo01(){ od = new OopDemo(); return od; } }
继承
对象的一个新类可以从一个现有的的类中派生,这个过程称为继承。新类继承了原始类的特性,新类成为原始类的派生类(子类),原始类称为新类的基类(父类),派生类可以从他的父类那里继承方法和属性。
多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去继承这个父类,我们的多个类就可以获取到父类中的成员了。
extends关键字。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class ExtendsDemo { public static void main(String[] args) { Dota dota = new Dota(); dota.start(); System.out.println("------------------------------------"); LOL lol = new LOL(); lol.start(); } } class Game{ String name; String agent; double version; public void start(){ System.out.println("游戏启动了"); } public void stop(){ System.out.println("游戏结束了"); } } class Dota extends Game{ } class LOL extends Game{ }
继承的特点:
只能做单继承,一个来只能有一个父类,不支持多继承。
Java支持多层继承(继承体系)
继承表达了一种is-a关系。
子类继承了父类,子类就拥有父类的所有属性,也可以继承父类的所有方法。
子类继承了父类,子类没有和父类一样的属性和方法,那么调用属性和方法的时候调用的是父类的方法和属性,如果子类也有父类有的属性和方法,子类new子类调用属性的时候调用的是子类自己的属性。
子类继承了父类:
子类有父类有,子类和父类都可以用;
子类没有父类有,子类父类都可以用;
子类有父类没有,子类可以用,父类不可以用。
当子类继承了父类,子类在实例化自己的时候,首先需要调用父类的无参构造方法。
如果两个类之间存在继承关系,那你必须在父类中存在一个无参构造方法,在创建父类的时候如果你在父类中写了有参构造方法,那么你必须将无参构造方法显式的写在父类中。
super关键字
super代表父类对象,是对父类对象的引用。
如果不在子类的构造方法中使用super(参数)的有参构造方法,那么你可以在父类中没有无参构造方法,但是对象子类中调用有参数构造方法。
继承中成员变量的特点:
父类成员访问属性 | 在父类中的含义 | 在子类中的含义 |
public | 对所有人开放 | 对所有人开放 |
protected |
只有包内其他类,自己和子类 可以访问 |
只有包内其他类,自己,子类 可以访问 |
缺省 | 只有包内其他类可以访问 |
如果子类和父类在同一个包内:只有包内其 他类可以访问,否则相当于private,不能访问 |
private | 只有自己可以访问 | 不能访问 |
public的成员直接成为子类的public成员,protected的成员也直接成为子类的protected的成员,Java中protected的意思是包内和子类可以访问,所以他比缺省的访问属性要宽一些。而对于父类中的缺省的未定义访问属性的成员来说,他们在父类中
所在包内是可见的,如果子类不属于父类的包,那么在子类里面,这些缺省属性和private的成员是一样的:不可见。父类中的private的成员在子类中任然存在,只是子类不能直接访问。我们不可以在子类中重新定义继承得到的成员的访问属性,如果
我们试图重新定义一个父类中已经存在的成员变量,那么我们是在定义一个与父类的成员变量完全无关的变量,在子类中我们可以访问这个定义在子类中的变量,在父类的方法中访问父类中的那个,尽管他们同名但是互不影响。
方法的重写:@Override,在子父类中,子类的方法和父类的方法完全一样(方法声明完全一致),子类重写了父类的方法(覆盖),当子类重写父类的方法后,使用子类对象调用的就是子类的方法。
方法的重载:@Overload,在一个类中,有多个重名的方法,但是参数不同(参数个数,参数的类型,参数的顺序),与返回值无关。
方法重写的应用场景:当父类的方法不能完全满足子类使用,这个时候子类重写父类的方法,并在方法中使用super关键字调用父类的方法,这样既可以保有父类的功能,也可以拥有子类特有的功能,
方法重写的注意事项:不能重写父类私有的成员方法,子类重写的方法的权限必须大于等于父类方法的权限。
继承中构造方法的执行顺序:
在子父类继承关系中,创建子类对象,调用子类的构造方法,如果子类构造方法的第一行代码没有调用父类的构造方法则会默认调用父类的无参构造;
我们可以使用super()在构造方法第一行调用父类的构造方法;
肯定会先执行父类的构造,因为要先给父类的成员变量初始化,子类可能会使用到。
多态
指允许不同类的对象对同一消息做出响应,多态性包括参数化多态性和包含多态性,多态性语言具有抽象/灵活/行为共享/代码共享的优势。方法的重写,重载与动态链接构成多态性,Java引入多态的概念原因之一就是弥补类的单继承带来的功能不足。
动态链接-->对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将调用子类中的这个方法。
父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在子类中的方法和属性它就望尘莫及了。
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类存在而父类不存在的方法,该引用是不能使用的,尽管是重载该方法,若子类重写了父类的某些方法,在调用这些方法时候,必定使用子类中重写的这些方法
(动态链接,动态调用)。
对于面向对象而已,多态分为编译时多态和运行时多态。其中编译是多态是静态的,主要是方法的重载,它是根据参数列表的不同来区分不同的函数,通过编译之后会变成两个不同的函数。在运行时是谈不上多态的。而运行时多态是动态的,他是通过动态
绑定来实现的,也就是所谓的多态性。
动态绑定:运行期间调用的方法,是根据其具体的类型决定的。
多态性就是相同的消息使得不同的类做出不同的响应。
Java实现多态有三个必要的条件:继承(实现关系也行),重写,向上转型(父类引用指向子类对象)。
多态的实现形式:继承和接口
多态的成员特点:
成员变量:编译时看的是左边,运行是看的也是左边;
成员方法:编译时看的是左边,运行是看的是右边;
静态方法:使用变量调用静态方法,相当于使用变量的类型的类名去调用,编译是看的是左边,运行看的也是左边。
编译时还没有创建对象,所有看的是左边(变量的类型),运行时成员方法看的是右边(具体对象类型),其他看的是左边。
引用数据类型之间的转换:
向上转型:由小到大,自动转换,父类引用指向子类对象,
向下转型:由大到小,强制转换,只有在多态发生之后,才能产生向下转型。
多态的优缺点:
缺点:无法直接访问子类特有的成员
优点:可以提高可维护性,提高代码的可扩展性。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo; public class Test02 { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b)); //A and A System.out.println(a1.show(c)); //A and A System.out.println(a1.show(d)); //A and D System.out.println(a2.show(b)); //B and A System.out.println(a2.show(c)); //B and A System.out.println(a2.show(d)); //A and D System.out.println(b.show(b)); //B and B System.out.println(b.show(c)); //B and B System.out.println(b.show(d)); //A and D } } class A { public String show(D d) { return "A and D"; } public String show(A a) { return "A and A"; } } class B extends A { public String show(B b) { return "B and B"; } public String show(A a) { return "B and A"; } } class C extends B { } class D extends B { }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.nike.demo01; public class Person { int id; public Person() { } public Person(int id) { this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public void walk(){ System.out.println("行走----------"); } public void eat(){ System.out.println("吃饭"); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.nike.demo01; public class Worker extends Person { String name; String sex; public Worker() { super(); // TODO Auto-generated constructor stub } public Worker(String name, String sex) { super(); this.name = name; this.sex = sex; } @Override public void walk() { super.walk(); System.out.println("工人去上班!"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public void play() { System.out.println("玩"); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.nike.demo01; public class TestWorker { public static void main(String[] args) { Worker worker = new Worker(); worker.walk(); Person p1 = new Worker(); p1.eat(); p1.walk(); System.out.println(p1.id); Worker w1 = (Worker) p1; w1.play(); System.out.println(w1.name); Worker w2 = (Worker) new Person(); } }