Java面向对象
Posted learnwhileucan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面向对象相关的知识,希望对你有一定的参考价值。
面向对象
面向对象:适合大型的复杂的项目,比如造一辆车,把各个部件(对象):轮子,车架,玻璃等等拼起来完成一整辆车的制造 (需要协作)
面向过程:适合简单的项目,比如开车,按照一定的过程,1.2.3.4, 第一步打火,第二步挂档,第三步启动,一步一步进行下去 (不需要协作)
这两种思想是相辅相成的,即使我们现在都是面向对象的思想,但你在构建每一个对象时,也是利用面向过程的思想把一个对象构建好。
对象和类
对象里面包含它的属性和行为,属性就是对象包含的变量,行为就是对象包含的方法。所以对象包含变量和方法。
类,就是对象的模板。例如,所有的狗都有四条腿 (相同的属性),都会叫(相同的行为),所以哈士奇,吉娃娃都属于狗这个类。
内存分析:栈stack,堆heap,方法区method area
JVM就包含栈,堆,方法区也包含在堆中
栈:栈表示方法执行的内存模型。每次调用方法,创建一个栈帧。JVM会为每一个线程创建一个栈,栈属于每一个线程私有,不能共享。栈的储存特点是连续储存空间,先进先出,后进后出。系统会自动分配栈,速度很快。
堆:存放创建好的对象和数组,就一个,所有线程可以共享。不连续内存空间,速度慢。
方法区(静态区):实际也是堆,用于存储类,常量的信息(不变的东西)。
构造器(构造方法)(constructor)
1.构造方法名称必须和类的名字保持一致。
2.通过new关键字调用
3.不能用return返回值
4.如果不定义构造器,系统会自动定义一个无参的构造器
this表示创建好的对象,所以this可以用于区别成员变量和局部变量。this不能用在static类和方法中,前面内存分析讲了,静态变量和方法是属于类的,不属于对象,所以this指不到任何对象。
JAVA的垃圾回收机制
1.发现无用对象
2.回收无用对象占用的空间
回收很简单,但是如何发现呢?主要靠以下两种算法:
1. 引用计数法
每一次对象被某个变量引用,都记录一次。通过记录被引用次数确定是否为垃圾。但是,当两个对象循环引用,计数器无法侦察。
2. 引用可达法
把程序所有引用关系做一张图,用算法对对象的引用进行跟踪,看是否可达。如果不可到达,则为无用对象。
Static关键字
static修饰的成员变量和方法,属于类,不属于对象。普通的变量和方法都属于对象。
静态方法无法调用普通方法和普通变量。普通方法和变量可以调用静态的。因为静态属于类,有类不一定有对象;但有对象一定有类。
JAVA的包,package的使用
JAVA的包,类似于电脑中的文件夹。一般在类的第一句话,把域名倒着写。
右键 - new - package也可以建包
一定要加包,方便管理,不要使用默认包
package cn.authorx public class Test { System.out.println("Hello World!") }
面向对象三大特性:继承,封装,多态
继承,instance of 判断从属关系
public class Main { public static void main(String[] args) { Student student = new Student(); student.name = "Jason"; student.major = "Finance"; student.studentID = "001"; System.out.println(student.name + "is a student, his ID is " + student.studentID + " and his major is " + student.major ); student.study(); student.rest(); System.out.println(student instanceof Person); } static class Person{ String name; String major; public void rest(){ System.out.println("take a break!"); } } static class Student extends Person{ String studentID; public void study(){ System.out.println("I am studying now!"); } } } 运行结果: Jasonis a student, his ID is 001 and his major is Finance I am studying now! take a break! true
封装
访问权限
工作中一般使用权限的规则:
1. 对于类的属性,一般直接用private,然后用getter and setter访问
public class computer{ private int seriesnumber; private String model; private String brand; }
2. 对于类里面的方法,除特殊情况,一般用public
多态
同一方法的调用,由于其中的对象不同,可能会有不同的行为。比如人.休息()这个方法,有的人可能睡觉,有的人看书,有的人玩游戏,不同的人对“休息”可能有不同的表现,这就是对象不同,行为可能不同。
要点:
1、多态指方法的多态,不是属性的多态,与属性无关
2、多态存在的三个必要条件:继承,方法重写,父类引用指向子类对象
3、父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了
/** *测试多态 */ public class Main { public static void main(String[] args) { Animal a = new Animal(); animalCry(a); Dog d = new Dog(); animalCry(d); //父类引用指向了子类对象,调用了子类的方法 } static void animalCry(Animal a){ a.shout(); } static class Animal{ public void shout(){ System.out.println("叫了一声!"); } } static class Dog extends Animal{ public void shout(){ System.out.println("汪汪汪!"); //继承和重写方法 } } class Cat extends Animal{ public void shout(){ System.out.println("喵喵喵!"); //继承和重写方法 } } }
抽象类/抽象方法
抽象类: 包含了抽象方法的类
抽象方法: 只有方法的声明, 没有方法体
要点:
1.、有抽象方法的类只能定义为抽象类
2.、抽象类不能实例化,不能用new来实例化抽象类
3、抽象类可以包含属性,方法,构造方法。构造方法也不能用new来实例,只能用来被子类调用
4、抽象类只能用来继承
5、抽象方法必须被子类实现
/** * 抽象类/抽象方法 */ public abstract class Animal { public abstract void run(); //有方法,没有方法体 } class Cat extends Animal { @Override public void run() { System.out.println("猫一路小跑...."); //子类必须重写方法 } }
接口
/** *接口 * 接口是什么? 接口就是一种规范,定义了一组规则,表示“如果你是...你就必须可以...”这一思想 接口的意义在于把设计和实现彻底分离 接口支持多继承 */ /** 把设计和实现彻底分离到底有什么好处? 例如:如何描述飞机,导弹,篮球,石头之间的关系?,如果用抽象类,继承,他们之间关系很有限 如果用接口共同描述他们都能 “飞” 这一行为,将会非常容易 */ public interface MyInterface { //接口中只有:常量和抽象方法! int Max_SPEED = 10000; int Max_HEIGHT = 1; public void fly(); } class Plane implements MyInterface { @Override public void fly() { System.out.println("飞机在飞"); } } class Basketball implements MyInterface { @Override public void fly() { System.out.println("篮球在飞"); } }
回调 callback (hook 钩子函数)
先写个接口
interface IMyFrame { void paint(); }
/** * 回调callback (hook 钩子函数) */ public class PaintFrame { public static void drawFrame(IMyFrame f){ System.out.println("Launch..."); System.out.println("Preparing..."); f.paint(); //调用paint方法 } /**上面这段代码只留下了一个paint方法,具体怎么实现要看你传给他什么对象,传什么用什么,本质是一种多态的实现。 * 这里这个paint方法有点像个钩子,你往上挂什么,他实现什么,所以又叫钩子函数*/ static class GameFrame01 implements IMyFrame{ public void paint(){ System.out.println("Painting GameFrame01..."); //实现接口,重写方法 } } static class GameFrame02 implements IMyFrame{ public void paint(){ System.out.println("Painting GameFrame02..."); } } public static void main(String[] args) { drawFrame(new GameFrame01()); //调用方法,new一个新的对象 } }
内部类 Innerclass
优点:
1、更好的封装,只允许外部类直接访问,不允许其他类直接访问,其他类想要访问需要通过外部类
2、可以直接使用外部类的所有属性(包括私有属性)和方法,在某些情况下比较方便
通常一个类只被另外一个类使用,才把它定义为这个类的内部类。
/** * 内部类 */ public class Outer { public static void main(String[] args) { Face f = new Face(); //要先有外部类成员,才能new内部类的成员和调用内部类的方法 Face.Nose n = f.new Nose(); n.breath(); Face.Ear e = new Face.Ear(); e.listen(); } } class Face{ String shape; String color; static String skin; class Nose{ String height; void breath(){ System.out.println("breathing..."); //Nose可以访问shape, color; Face不能访问height } } static class Ear{ void listen(){ System.out.println("I‘m listening..."); //静态内部类不可以访问外部类的普通属性,shape,color。但是可以访问外部类的静态属性:skin } } }
以上是关于Java面向对象的主要内容,如果未能解决你的问题,请参考以下文章