object-oriented programming
java编程核心思想就是面向对象
面向对象三大特性
①封装 | ②继承 | ③多态
对于描述复杂的事物,为了从宏观上把握、 从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
package com.ylq;
public class Demo01 {
public static void main(String[] args) {
System.out.print(whoMax(99,97));
}
public static int whoMax(int x, int y){
return x>y? x:y;
}
// 修饰符 返回值类型 方法名(参数列表){
// 方法体
// return [返回值];
// }
}
package com.ylq;
public class Demo02 {
public static void main(String[] args) {
Archer shiLang = new Archer();
shiLang.selfIntroduction();
shiLang.setNew(shiLang,1,"卫宫士郎");
shiLang.selfIntroduction();
}
}
class Archer {
int id = 0;
String name = "吉尔伽美什";
public static void setNew(Archer newOne,int id,String name) {
newOne.id = id;
newOne.name = name;
}
public void selfIntroduction() {
System.out.println("I\‘m an Archer,"+name+",ID"+id); }
}
上例中因为传递的参数是一个对象,故属于引用传递。方法内部的赋值行为会影响方法外部。
tips:
一个程序最好只有一个main方法,是程序的入口
一般会创建一个主启动类Application,在这个类中写main方法
一个类即使什么都不写也会自动生成一个构造方法,如如上例中的
Archer()
构造方法也可以显示地定义:
- 必须与类同名,而且不能写返回值类型(void也不能写)
- 显示定义可以用来初始化一些信息
- 可以无参构造也可以有参构造
- new关键字本质是调用构造器
- 定义有参构造的时候必须显示地定义一个无参构造
- intelij IDEA用快捷键alt+insert可以快速创建构造器
package com.ylq.demo03;
public class Ninja {
int id;
String name;
public Ninja() {
this.id = 0;
this.name = "小胖";
}
public Ninja(int fpID,String fpName){
this.id = fpID;
this.name = fpName;
};
public void selfIntroduce() {
System.out.println("我是"+this.name+",NO."+this.id+".");
}
}
package com.ylq.demo03;
public class Application {
public static void main(String[] args) {
Ninja xiaoPang = new Ninja();
xiaoPang.selfIntroduce();
Ninja longMa = new Ninja(1,"龙马");
longMa.selfIntroduce();
}
}
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉。
- 低耦合:尽量暴露少量的方法给外部使用。
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护性增加了
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是“扩展”。子类是父类的扩展。
JAVA中的类只有单继承,没有多继承!
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
子类和父类之间,从意义上讲应该具有“is a”的关系。
object类
super
方法重写
ctrl+h可以查看继承树
package com.ylq.demo05;
public class Spirit {
private int id;
private String name;
public Spirit() {
}
public Spirit(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.ylq.demo05;
public class Rider extends Spirit {
private String mountName;
public Rider() {
}
public Rider(int id, String name) {
super(id, name);
}
public Rider(String mountName) {
this.mountName = mountName;
}
public Rider(int id, String name, String mountName) {
super(id, name);
this.mountName = mountName;
}
public String getMountName() {
return mountName;
}
public void setMountName(String mountName) {
this.mountName = mountName;
}
public void selfIntroduce(){
System.out.println("我是Rider,真名"+this.getName()+",ID"+this.getId()+",我的坐骑是"+getMountName()+".");
}
}
package com.ylq.demo05;
public class Application {
public static void main(String[] args) {
Rider medusa = new Rider(1,"美杜莎","小白马");
medusa.selfIntroduce();
}
}
Java中所有的类都默认直接或间接继承Object类
调用子类的无参构造的时候默认隐式调用父类无参构造
想显示调用父类构造器super()必须放在第一行
构造器中调用本对象的构造器this()也必须放在第一行
故上面两个构造器调用只能用一个
和this一样都是代词。super可以指代父类对象,甚至可以指代父类构造函数。
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小 public > protected > default > private
- 抛出的异常:范围可以缩小但不能扩大 ClassNotFoundException --> Exception
下例中的非静态写法就是方法的重写
package com.ylq.demo06;
public class Father {
public static void test() {
System.out.println("测试了父类");
}
public void testWithoutStatic() {
System.out.println("测试了父类withoutStatic");
}
}
package com.ylq.demo06;
public class Son extends Father {
public static void test() {
System.out.println("测试了子类");
}
public void testWithoutStatic() {
System.out.println("测试了子类withoutStatic");
}
}
package com.ylq.demo06;
public class Application {
public static void main(String[] args) {
Son pang = new Son();
pang.test();
//静态方法:
//分别调用Father和Son的test
//方法的调用只和左边定义的数据类型有关系
//父类的引用指向子类
Father shou = new Son();
shou.test();
//非静态方法:
//都是调用Son的test
//方法的调用只和构造函数的引用有关
//子类重写了父类的方法
pang.testWithoutStatic();
shou.testWithoutStatic();
//结果:
//测试了子类
// 测试了父类
//测试了子类withoutStatic
// 测试了子类withoutStatic
}
}
不能重写的情况
static 方法属于类,不属于实例
final 常量
private 私有的方法
类内部 | 本包 | 子类 | 外部包 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
package com.ylq.demo07;
public class Application {
public static void main(String[] args) {
Object naMei = new Navigator();
System.out.print((naMei instanceof Navigator)+" | "); // √
System.out.print((naMei instanceof Pirate)+" | "); // √
System.out.print((naMei instanceof Object)+" | "); // √
System.out.print((naMei instanceof Captain)+" | "); // ×
System.out.print((naMei instanceof Warrior)+" | "); // ×
System.out.print((naMei instanceof String)+" | \n"); // ×
System.out.println("---------------------------------------");
Pirate luFei = new Captain();
System.out.print((luFei instanceof Navigator)+" | "); // ×
System.out.print((luFei instanceof Pirate)+" | "); // √
System.out.print((luFei instanceof Object)+" | "); // √
System.out.print((luFei instanceof Captain)+" | "); // √
System.out.print((luFei instanceof Warrior)+" | "); // ×
//System.out.print((luFei instanceof String)+" | \n"); 编译时报错
System.out.println("---------------------------------------");
Warrior zoro = new Warrior();
//System.out.print((zoro instanceof Navigator)+" | "); 编译时报错
System.out.print((zoro instanceof Pirate)+" | "); // √
System.out.print((zoro instanceof Object)+" | "); // √
//System.out.print((zoro instanceof Captain)+" | "); 编译时报错
System.out.print((zoro instanceof Warrior)+" | "); // √
//System.out.print((zoro instanceof String)+" | \n"); 编译时报错
System.out.println("---------------------------------------");
}
}
- 类型转换低转高,可以自动转换;高转低,需要强制类型转换
- 引用型数据中:父类-高,子类-低
- Object obj = String(); 左高右低,低转高,自动转换
- 子类强转父类会丢失一些方法
多态小结:
static的属性和方法属于类,不用实例化成对象就可以调用。
静态属性不因对象变多而增加,一直就一个。
静态方法在加载类的时候就加载了,存在堆得方法区中,可以直接 类.方法 调用
静态代码块:只在加载类的时候执行一次,在构造函数之前
static{
...
}
package com.ylq.demo08;
import org.w3c.dom.ls.LSOutput;
public class CodeBlock {
{
System.out.println("匿名代码块");
}
static{
System.out.println("静态代码块");
}
public CodeBlock() {
System.out.println("构造函数");
}
public static void main(String[] args) {
CodeBlock pang = new CodeBlock();
System.out.println("-----------------------");
CodeBlock shou = new CodeBlock();
}
}
/*
静态代码块
匿名代码块
构造函数
-----------------------
匿名代码块
构造函数
*/
import static java.lang.Math.random;
tips: final修饰的东西不能继承给子类,final修饰的类断子绝孙了
package com.ylq.demo09;
public abstract class Mood {
protected abstract void influence();
}
抽象类中的抽象方法可以只有名字,没有具体实现的代码
package com.ylq.demo09;
public class Happy extends Mood {
@Override
protected void influence() {
System.out.println("心情越快,乐观向上");
}
}
抽象类有局限性,因为继承的单继承特性。但是通过接口可以实现多继承。
故实际开发中接口用得比较多。
普通类:只有具体实现。
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范,自己无法写方法。体现了约束和实现分离。
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是。。则必须能。。”的思想。如果你是坏人,则必须欺负好人。
接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。
OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如C++、Java、C#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象
声明类的关键字是class,声明接口的关键字是interface
接口中的方法默认都是public abstract
接口的实现类一般以impl结尾(implement使实现)
接口中定义的属性都默认为常量,省略了public static final
package com.ylq.demo10;
public interface UserService {
int AGE = 20;
void add();
void delete();
void update();
void query();
}
package com.ylq.demo10;
public interface TimeService {
void setTime();
}
package com.ylq.demo10;
public class UserServiceImpl implements UserService,TimeService{
@Override
public void setTime() {
}
@Override
public void add() {
}
@Override
public void delete() {
}
@Override
public void update() {
}
@Override
public void query() {
}
}
1.成员内部类
2.静态内部类
3.局部内部类 (比如在方法内写的类)
4.匿名内部类 (new Allpe.eat();没有把创建的对象指向任何引用名,直接用)
package com.ylq.demo11;
public class Outer {
private int id = 10;
public class Inner {
protected void letsGo(){
System.out.println("内部类起飞,还能输出外部类私有属性:"+id);
}
}
}
package com.ylq.demo11;
public class Application {
public static void main(String[] args) {
Outer littleBoy = new Outer();
Outer.Inner devil = littleBoy.new Inner();
devil.letsGo();
}
}
原文:https://www.cnblogs.com/ylq167/p/14401860.html