一、 面向对象基础部分
1、this、super关键字
2、static、final关键字
3、引用传递介绍和应用
4、静态块、代码块、同步块
5、构造方法、匿名对象、单例定义以及实现
6、内部类、匿名内部类应用
二、 面向对象高级部分
1、继承的进一步讨论
2、接口和抽象类进一步讨论
3、object类和包装类进一步讨论
1、this、super关键字
- /**
- * @author Administrator
- *
- * @description 测试基类
- * @history
- */
- public class BaseTest {
- protected String pwd; // 定义protected属性pwd
- public BaseTest(){
- // 无参数构造方法
- }
- public String sayHelloWorld(){
- return "hello world";
- }
- }
- /**
- * @author Administrator
- *
- * @description this,super关键字测试类
- * @history
- */
- public class MyTestDemo extends BaseTest{
- // notes:测试使用而已,代码功能模拟而已
- private String username; // 定义用户昵称私有属性private修饰
- private String password;
- public MyTestDemo(String username){ // 构造方法
- this();// this()调用无参数构造方法
- this.username = username; // this.属性访问当前username属性
- // super.属性调用父类属性
- this.password = super.pwd;
- }
- public MyTestDemo(){
- // 无参数构造方法
- super(); // 调用父类无参数构造方法
- }
- public void sayHello(){
- this.sayWord(); // this.方法调用当前对象的sayWord方法
- super.sayHelloWorld(); // super.方法调用父类sayHelloWorld方法
- }
- public String sayWord(){
- return "hello this";
- }
- // this表示当前对象
- public boolean equals(Object obj){
- MyTestDemo other = (MyTestDemo)obj; // 传入的比较对象,强制转换操作
- // 简单模拟,如果对象的username属性值相同那么就认为相同
- if(this == other){
- return true;
- }
- if(other instanceof MyTestDemo){
- if(this.username.equals(other.username)){
- return true;
- }
- }
- return false;
- }
- /**
- *@description
- *@param args
- */
- public static void main(String[] args) {
- // this关键字绑定了当前该对象,通过this.属性、this.方法
- // super关键字用在子类要调用父类的属性或者方法中,通过super.属性、super.方法
- MyTestDemo obj1 = new MyTestDemo("hello-java"); // 定义并实例化对象
- obj1.sayHello(); // 调用对象的sayHello方法
- MyTestDemo obj2 = new MyTestDemo("hello-java");
- // equals方法传入的参数类型为object,传入的obj2会自动向上转型处理
- boolean result = obj1.equals(obj2);
- System.out.println(result); // true
- }
- }
2、static、final关键字
- /**
- * @author Administrator
- *
- * @description final和static关键字学习
- * @history
- */
- public class FinalAndStaticTestDemo {
- /**
- *@description
- *@param args
- */
- public static void main(String[] args) {
- // final关键字主要有三种场景
- // 1、final定义的变量为常量,比如基本数据类型的值一旦初始化了不能改变
- // 2、final定义的类为终结类,不能再被继承,比如string类型
- // 3、final定义的方法为终结方法,不能被覆写,否则编译器会报错
- final String str = "helloworld"; // final修饰变为常量不能改变
- //str = "hellojava"; // eclipse提示:The final local variable str cannot be assigned.
- // 进一步思考下面两个问题
- String s1 = "hello";
- String s2 = "hello1";
- final String s = s1;
- s1 = s2;
- System.out.println(s); // hello还是hello1呢?
- // 引用不可变,内容可变是这个意思吗?
- StringBuffer sb = new StringBuffer();
- sb.append("hello");
- final String fs = sb.toString();
- final StringBuffer fsb = sb;
- sb.append("world");
- System.out.println(fs);// hello还是helloworld呢?
- System.out.println(fsb.toString()); // hello还是helloworld呢?
- // static关键字比较类似也有下面三种场景
- // static修饰的变量为静态变量,它不同于对象/实例变量,是关联在某个类上的
- // static修饰的类为静态类
- // static修饰的方法为静态方法,它也不同于对象/实例方法,是关联在某个类上的
- // static int i = 100;
- // static class HelloWorld{ //... }
- // public static void sayHeloWorld(){ //... }
- }
- // 静态变量和对象变量
- static int i = 100; // 定义静态变量i
- int j = 100; // 定义成员变量/实例变量
- public static void sayHelloWorld(){ // 定义静态方法sayhelloworld
- System.out.println("hello world");
- }
- static class HelloWorld{ // 定义内部类
- // ...
- }
- }
3、引用传递介绍和应用
- /**
- * @author Administrator
- *
- * @description 引用传递的简单学习
- * @history
- */
- class DemoTest{
- String ide = "eclipse"; // 为了方便访问暂不封装
- }
- public class MyDemoTest{
- /**
- *@description
- *@param args
- */
- public static void main(String[] args){
- // 对象属性值访问和变更
- DemoTest dt1 = new DemoTest();
- System.out.println(dt1.ide); // eclipse
- dt1.ide = "netbeans"; // 改变ide属性值
- System.out.println(dt1.ide); // netbeans
- function(dt1); // 调用方法function
- System.out.println(dt1.ide); // jcreator
- // String类赋值和变更
- String ide = "eclipse";
- function(ide);
- System.out.println(ide); // eclipse而不是netbeans
- }
- private static void function(String ide) {
- ide = "netbeans"; // 赋值为netbeans
- }
- // 测试方法function
- private static void function(DemoTest dt2) {
- dt2.ide = "jcreator"; // 改变ide属性值
- }
- }
4、静态块、代码块、同步块
- /**
- * @author Administrator
- *
- * @description 静态块、代码块、同步块学习测试类
- * @history
- */
- class BlockDemo {
- static {
- // 在类中定义的static{ //...}为静态代码块
- // 静态代码块的程序只会被初始化一次
- System.out.println("BlockDemo->static");
- }
- {
- // 在类中定义的{ //...}为构造代码块
- // 构造代码块和对象一起初始化的
- System.out.println("BlockDemo->{}");
- }
- public BlockDemo() {
- System.out.println("BlockDemo->BlockDemo");
- }
- // 构造方法、构造代码块和静态代码块初始化顺序呢?
- // 静态块、构造块、构造方法 // 表面初步分析,具体有待研究
- }
- public class MyDemo {
- /**
- * @description
- * @param args
- */
- public static void main(String[] args) {
- // 静态块、代码块、同步块
- {
- // 在方法中用{ //... }定义的为普通代码块
- int x = 100;
- System.out.println(x); // 100 相当于局部变量
- }
- int x = 200;
- System.out.println(x); // 200
- new BlockDemo();
- new BlockDemo();
- // BlockDemo->static static代码块只会被初始化一次
- // BlockDemo->{}
- // BlockDemo->BlockDemo
- // BlockDemo->{}
- // BlockDemo->BlockDemo
- }
- }
5、构造方法、匿名对象、单例定义以及实现
- /**
- * @author Administrator
- *
- * @description 构造方法、匿名对象学习测试类
- * @history
- */
- public class MyDemoTest {
- private String username; // 定义私有属性username
- // 构造方法的作用是初始化操作
- // 构造方法是一种特殊的方法,构造方法也有重载
- public MyDemoTest(){
- // 无参数构造方法
- }
- public MyDemoTest(String username) { // 定义构造方法
- this.username = username; // 对属性初始化赋值操作
- }
- /**
- *@description
- *@param args
- */
- public static void main(String[] args) {
- // 实例化一个匿名对象
- // 匿名对象不在栈中开辟空间赋地址值
- new MyDemoTest("eclipse");
- }
- }
- /**
- * @author Administrator
- *
- * @description 单例学习测试类
- * @history
- */
- class Singleton {
- private Singleton() {
- // 将构造方法私有化,外部不能直接调用
- System.out.println("private Singleton(){//...}");
- }
- // 饿汉式获取单例代码
- private static Singleton instance = new Singleton();
- // 对外提供一个getInstance方法获取单例
- public static Singleton getIntance() {
- return instance;
- }
- }
- class Singleton2{
- private Singleton2(){
- // 构造方法私有化,外部不能直接调用
- System.out.println("private Singleton2(){//...}");
- }
- // 懒汉式获取单例代码
- private static Singleton2 instance = null;
- private static Object lock = new Object();
- // 获取单例方法,效率比较低
- // 每次进入都要进行锁判断,而实际情况我们是第一次null比较特殊
- /*public static Singleton2 getIntance(){
- synchronized (lock) {
- if (instance == null) { // 如果为null进行实例化对象操作
- instance = new Singleton2();
- }
- }
- return instance;
- }*/
- // 上面同步代码的另外一种写法如下,效率比较低
- // public static synchronized getInstance(){ //...}
- // 对同步代码进行改写
- public static Singleton2 getIntance(){
- if(instance == null){
- synchronized(lock){
- if(instance == null){ // 进行双重检验操作
- instance = new Singleton2();
- }
- }
- // 如果换为下面这种形式那么就可能不是产生一个实例对象了
- /*synchronized(lock){
- instance = new Singleton2();
- }*/
- }
- return instance;
- }
- }
- public class SingletonTest {
- /**
- *@description
- *@param args
- */
- public static void main(String[] args) {
- Singleton.getIntance(); // 饿汉式获取单例
- Singleton2.getIntance(); // 懒汉式获取单例
- }
- }
6、内部类、匿名内部类应用
- class Outer{ // 定义外部类
- private String info = "helloworld" ; // 定义外部类属性
- private static String info2 = "helloeclipse"; // 定义静态变量
- class Inner{ // 定义内部类
- public void print(){
- // 内部类的好处之一:直接访问外部类属性
- System.out.println(info) ; // 直接访问外部类属性
- }
- }
- static class StaticInner{ // 通过static定义的内部类为外部类
- public void print(){
- System.out.println(info2);
- }
- }
- public void fun(){
- new Inner().print() ; // 通过内部类的实例化对象调用方法
- }
- }
- /**
- * @author Administrator
- *
- * @description 内部类以及匿名内部类学习测试类
- * @history
- */
- public class InnerClassDemo{
- /**
- *@description
- *@param args
- */
- public static void main(String[] args){
- new Outer().fun() ; // 调用外部类的fun()方法
- // 另外一种实例化方式
- Outer out = new Outer();
- Outer.Inner in = out.new Inner();
- in.print();
- // 通过外部类.内部类实例化内部类对象
- //StaticInner sin = new Outer.StaticInner(); //需要导入外部类所在的包
- //sin.print();
- }
- }
二、 面向对象高级部分
1、继承的进一步讨论
- class Base{
- // 定义基类
- void print(){
- System.out.println("Base->print()");
- }
- public void print1(){
- // 父类方法的访问权限,子类覆写该方法的时候不能降低权限
- }
- }
- class ZiLei extends Base{
- // 定义子类覆写print方法
- void print(){
- // 子类访问父类中的方法,前面super关键字内容
- // super.print();
- System.out.println("Super->print()");
- }
- /*void print1(){
- // Cannot reduce the visibility of the inherited method from Base
- }*/
- // 覆写override和重载overload区别
- // 覆写是父类子类之间的关系,重载是同一个类之间的关系
- }
- /**
- * @author Administrator
- *
- * @description 继承中的方法覆写
- * @history
- */
- public class OverrideDemo{
- public static void main(String args[]){
- new ZiLei().print(); // 调用的内容是覆写后的方法实现
- // 另外java中只能够单继承,不同于C++,但是可以多重继承
- /*class A{
- // ...
- }
- class B extends A{ //class C extends A,B{ // ...}编译错误
- // ...
- }
- class C extends B{
- // ...
- }*/
- }
- }
2、接口和抽象类进一步讨论
- /**
- * @author Administrator
- *
- * @description 接口测试类
- * @history
- */
- interface Interface{
- public static final String INFO = "helloeclipse";
- public void print(); // 定义方法
- public abstract void printInfo();
- }
- class I implements Interface{
- public void print() {
- // 方法实现
- System.out.println(INFO); // helloeclipse
- }
- public void printInfo() {
- // ...
- }
- }
- public class InterfaceTestDemo {
- /**
- *@description
- *@param args
- */
- public static void main(String[] args) {
- // 接口interface
- // 接口interface和抽象类abstract一样不能直接实例化必须通过子类来实现
- new Interface(){
- public void print() {
- // 匿名内部类,方法实现
- System.out.println(INFO); // helloeclipse
- }
- public void printInfo() {
- // ...
- }
- };
- // 接口和抽象类对比,接口更像一种规范、抽象类更像一种模板
- // 抽象类定义一些公共的实现,以及一些未实现的方法交给子类具体实现特定的功能-模板方法
- }
- }
- /**
- * @author Administrator
- *
- * @description 抽象类学习测试类
- * @history
- */
- abstract class Abstract{ // 定义抽象类
- public final static String INFO = "helloeclipse"; // 定义全局变量/常量
- abstract public void print(); // 定义抽象方法
- // 抽象类不能直接实例化,抽象类的子类如果不是抽象类那么一定要实现所有的抽象方法
- }
- class AbstractZiLei extends Abstract{ // 定义抽象子类
- public void print() { // 实现子类方法
- System.out.println(INFO);
- }
- }
- public class AbstractTestDemo {
- /**
- *@description
- *@param args
- */
- public static void main(String[] args) {
- // 接口和抽象类interface,abstract
- // 抽象类:含有抽象方法的类叫做抽象类用abstract修饰的
- new Abstract(){
- public void print() {
- System.out.println(INFO); // 匿名抽象类实现
- }
- };
- // 抽象类能不能被final修饰呢?final定义的类为终结类,抽象类是需要子类来实现的
- // final abstract class Abstract{ //... } // 编译报错
- }
- }
3、object类和包装类进一步讨论
- /**
- * @author Administrator
- *
- * @description Object类学习测试类
- * @history
- */
- public class ObjectTestDemo {
- /**
- *@description
- *@param args
- * @throws ClassNotFoundException
- */
- public static void main(String[] args) throws ClassNotFoundException {
- // Object类学习测试代码
- // 1、toString方法
- // 2、equals和hashCode方法
- // 3、getClass方法
- ObjectTestDemo otd = new ObjectTestDemo();
- System.out.println(otd);
- System.out.println(otd.toString());// 现实调用toString方法
- /*
- * Object类中toString方法
- * public String toString() {
- return getClass().getName() + "@" + Integer.toHexString(hashCode());
- }
- * Object类中equal方法
- * public boolean equals(Object obj) {
- return (this == obj);
- }*/
- // 定义昵称和年龄属性,如果昵称和年龄相同则equal方法返回true
- ObjectTestDemo otd1 = new ObjectTestDemo();
- otd1.nickname = "eclipse";
- otd1.age = 20;
- ObjectTestDemo otd2 = new ObjectTestDemo();
- otd2.nickname = "eclipse";
- otd2.age = 20;
- System.out.println(otd1==otd2); // false
- System.out.println(otd1.equals(otd2)); // 如果不覆写的话返回的一直是false
- // hashCode方法和equals方法的关系,没有绝对的关系
- // 具体参看源代码的注释说明,在实际用中尽量同时覆写这两个方法,保持一致性
- // public final native Class<?> getClass();
- // getClass方法是一个本地方法,调用底层代码,返回当前对象对应的一个类对象实例
- // 类对象实例,理解为内存中对应的那份字节码对象,java反射内容初步学习
- // 通过字节码对象构造出一个个的对象实例
- Class claz = otd.getClass();
- Class claz1 = ObjectTestDemo.class;
- Class claz2 = Class.forName("ObjectTestDemo"); // 类的完整路径
- System.out.println(otd.getClass()); // class ObjectTestDemo
- // VM内存中只会产生一份字节码对象
- System.out.println(claz == claz1); // true
- }
- // 方法模拟,添加两个属性昵称和年龄
- private String nickname;
- private int age;
- // 注意参数类型不要写成了ObjectTestDemo
- public boolean equals(Object obj) {
- ObjectTestDemo otd = (ObjectTestDemo) obj; // 向上转型,强制转换
- if (this == otd) {
- return true;
- }
- if (otd instanceof ObjectTestDemo) {
- if (this.nickname.equals(otd.nickname) && this.age == otd.age) {
- return true;
- }
- }
- return false;
- }
- public String toString(){
- return "helloworld"; //覆写toString方法,返回helloworld
- }
- }