面向过程:侧重分步骤,考虑完成该功能的过程(自己一步一步干)
侧重分模块(找人分发任务解决任务)
总结
面向对象优势:可扩展,可维护,灵活性高,程序耦合度低
面向对象缺点:性能比面向过程相对较差
实例化对象:Student s1 = new Student();
通过get和set方法获取和设置成员属性
JavaBean
是一种Java
语言写成的可重用组件,它是一个类(类必须是具体的公共的,并且具有无参构造器)
get
和set
方法get
和set
方法的作用
main()
方法压栈null
访问成员变量时)javac
编译时会改成类名调用静态变量(所以空指针也不影响)对象中第一个成员变量,保存了当前对象的内存地址(不能出现在静态方法中)
修饰符 用来标注静态属性 如果没有使用static
为成员属性
main()
方法之前运行) 只执行一次代码块:无名称方法 、自动调用
访问一个类的静态属性的时候 才会加载该类到内存中
实例语句块 可看做无名字成员方法
把所有组成部分组合到一起,还可以通过权限控制修饰符将数据隐藏起来,可以控制用户对类数据的修改程度
适当的封装可以让代码更容易理解,易于维护,更提高了代码的安全性
放在 package
之下 class
之上
静态导入
导入某个类的某个静态变量
范围 | public | protected | default | private |
---|---|---|---|---|
同类 | ✔️ | ✔️ | ✔️ | ✔️ |
同包 | ✔️ | ✔️ | ✔️ | ❌ |
子类 | ✔️ | ✔️ | ❌ | ❌ |
全局 | ✔️ | ❌ | ❌ | ❌ |
从一个已有的类中衍生出一个新的类。该类往往包含着父类的特征,还可以新增特有的属性
必须有继承关系
源码注解
编译注解
运行时注解
可放置在
父类引用指向子类对象
使用父类创建的引用类型变量 可以找到子类对象
父类 变量名 = new 子类();
向上转型(由子类转换为父类) 类似于自动转换类型
非成员方法
会丢失子类特有的属性
成员方法 如果子类重写了父类的成员方法则调用子类的成员属性
非成员方法 调用父类方法
public class Poly {
public static void main(String[] args) {
Sup sub = new Sub();
// 2
System.out.println(sub.age);
sub.m1();
// Son m2
sub.m2();
// sub.m3();
}
}
class Sup{
int age = 2;
public void m1(){
System.out.println("Father m1");
}
public void m2(){
System.out.println("Father m2");
}
}
class Sub extends Sup{
int age = 1;
public void m2(){
System.out.println("Son m2");
}
public void m3(){
System.out.println("Son m3");
}
}
判断某个对象是否由某个类实例化而来
向下转型(由父类转换为子类)
父类 变量名 = new 子类();
通过子类对象,调用继承父类的成员方法时 此时上下文环境为多态环境
public class Poly_05 {
public static void main(String[] args) {
// Sup sup = new Sub();
// // 2 父类
// System.out.println(sup.age);
// // 父类 因为子类没有
// sup.m1();
// // 子类 因为覆写
// sup.m2();
// // 报错,因为父类没有,多态会丢失子类特有属性
// // sup.m3();
// // 向下转型
// Sub sub = (Sub) sup;
// // 1 子类
// System.out.println(sub.age);
// // 父类 继承
// sub.m1();
// // 子类 因为子类有
// sub.m2();
// // 子类,又没有使用多态
// sub.m3();
Sub sub = new Sub();
sub.m1();
}
}
class Sup {
int age = 2;
public void m1() {
/**
* this : 是对象中第一个成员变量,保存当前对象的内存地址
*
* this既然保存当前对象内存地址,那么this的类型 可以是当前类类型,可以是父类类型
*
* this写在哪个类中,哪个类就是当前类 所以 当前类 是Sup 父类 是 Object
*
* 因为this能调用当前类中所有的属性,并没有丢失,所以this是Sup 当前类类型
*
* Sup this;
*
* this : 哪个对象调用这个成员方法,this就指向谁
*
* 最终是Sub调用的m1方法,所以this 指向 Sub
*
* Sup this = Sub;
*/
// System.out.println("父类m1");
System.out.println(this);
// 2 父类
System.out.println(this.age);
System.out.println(this.sakjdkashdhqwrjnfaksf);
System.out.println(age);
// 子类
m2();
// 报错
// m3();
}
public void m2() {
System.out.println("父类m2");
}
}
class Sub extends Sup {
int age = 1;
public void m2() {
System.out.println("子类m2");
}
public void m3() {
System.out.println("子类m3");
}
}
abstract
修饰符 用来修饰抽象类和抽象方法
abstract
修饰的类是抽象类,并且抽象类不能创建对象而且抽象类一般主要用于被继承
abstract
修饰的方法是抽象方法。该方法没有方法体,不实现功能,用于让不同的子类实现方法
抽象方法必须在抽象类中,而抽象类中可以存在普通方法
抽象类中可看作特殊的类,只不过不能创建对象而已
abstract
和final
不能同时出现
abstract
修饰interface
关键字
1.8之前接口是完全抽象的,只允许出现抽象方法和常量(psf
)
在接口中只有常量没有变量,并且psf
可以省略 且权限控制默认是public
抽象方法的 abstract
可以省略
interface A{
int age = 1;
// 默认方法
default void dmethod(){
System.out.println("默认方法");
}
}
class B{
void m(){
System.out.println(A.age);
}
}
Object
是Java提供的根类 所有类都直接或间接继承Object
java.lang.Object
在java.lang
包下 核心包下的所有类不需要导入
==
基本类型比较值大小,引用类型比较地址
==
是 equal()
的默认底层实现
默认的 equals()
比较地址
JVM 跨平台 多线程 面向对象 自动垃圾回收
垃圾 没有任何引用指向该对象的时候,该对象成为垃圾对象
垃圾被回收时 自动调用该对象的 finalize()
方法 是在对象生命结束时候被调用
System.gc()
程序员可以建议JVM进行垃圾回收
类与类之间的关系详见 这里
class A{
class B{
}
}
等同于成员变量 不能有静态声明
内部类可以使用权限控制修饰符
可以访问外部类的私有化(被 private
修饰)属性
成员内部类可以直接访问外部类的所有数据
此时 B
类的全类名为 A$B
class A{
private int a = 1;
private static int b = 1;
static class B{
int c = 1;
static int d = 1;
public void method(){
// System.out.print(a);
A aaa = new A();
System.out.print(aaa.a);
System.out.print(b);
}
}
}
final
修饰 1.8后final
可以省略class A{
void method(){
class B{
}
}
}
此时B
类的全类名为 A$1B
如果内部类名重复 则为外部类类名$2内部类类名
当一个方法的参数需要传入一个类对象时,可以使用匿名内部类
new 实现接口(){
//匿名内部类类体部分
}
实现接口 接口没有构造函数所以为空参数
new 父类构造器(实参列表){
//匿名内部类类体部分
}
调用父类构造器可以为空参数,也可以传入参数
//接口部分
interface Product{
public double getPrice();
public String getName();
}
public class Anonymous{
public void test (Product p){
System.out.println(p.getName()+"--------"+p.getPrice());
}
public static void main(String[] args ){
Anonymous as = new Anonymous();
//此处实现接口并实现抽象方法
as.test(new Product(){
//实现方法
public double getPrice( ){
return 8888;
}
//实现方法
public String getName(){
return "I can do it ";
}
});
}
}
上面代码很简单,就是定义了一个类Anonymous
,在类里定义了一个test
方法。然后就是创建Anonymous对象,调用他的实例方法test()
不过调用test()
方法时,要传入一个Product
对象。但是由于Product
是一个接口,无法创建对象,所以要实现该接口。因此此处采用匿名内部类的方式进行,并实现接口中全部的抽象方法
无需通过实现接口或者继承抽象类的方式来实现。但是使用匿名内部类的优点是显而易见的,可以少些代码,而且代码更加简洁