JavaSE基础-面向对象编程
1-初识面向对象
1.1面向过程&面向对象
1.1.1-面向过程思想:
-
步骤清晰简单,第一步做什么,第二步做什么.......。
-
面对过程适合处理一些简单的问题。
1.1.2-面向对象思想:
-
物以类聚,分类的思维模式。
-
面向对象适合处理复杂的问题,适合处理需要多人协作的问题。
-
面向对象主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一个事物在整个解决问题的步骤中的行为。
2-对象
2.1-初识对象
2.1.1-定义
-
对象的含义是指具体的某一个事物,即在现实生活中能够看得见摸得着的事物。
-
在面向对象程序设计中,对象所指的是计算机系统中的某一个成分。
-
在面向对象程序设计中,对象包含两个含义,其中一个是数据,另外一个是动作。对象则是数据和动作的结合体。对象不仅能够进行操作,同时还能够及时记录下操作结果。
2.1.2-创建
-
使用new关键字创建对象。
new
-
使用new关键字创建对象的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
2.2对象的代码详解
-
创建类Parson()
package Target;
public class Parson {
String name;
int age;
public Parson() {//无参构造方法
}
public Parson(String name, int age) {//有参构造方法
this.name = name;
this.age = age;
}
}
-
创建类Application(实现类)
package Target;
public class Application {
public static void main(String[] args) {
//创建一个对象 parson并往Parson类的Paerson方法传入数据
Parson parson = new Parson("moxia", 21);
//调用了Parson类中name属性
System.out.println(parson.name);
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/0b9d8a3693a685d52b32c7d30315ed7a.png)
2.3-构造方法:
2.3.1-初识构造方法
2.3.1.1-构造方法有的分类
-
无参构造方法
-
有参构造方法。
2.3.1.2-构造方法的特点:
-
必须和类名相同。
-
必须没有返回类型,也不能写void。
-
写有参构造方法就要写无参构造方法
注:如果一个类中没有写任何的构造方法,JVM 会生成一个默认的无参构造方法。
2.3.2-构造方法代码详解
package Target;
public class Dom1 {
private int a; //私有属性a
public Dom1() {//无参构造方法
}
public Dom1(int a) {//有参构造方法
this.a = a;
}
}
注:在不写有参构造方法时无参构造方法在类会自动生成。
3-面向对象的三大特性
3.1-封装
3.1.1-初识封装
3.1.1.1-什么是封装
-
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
-
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
-
要访问该类的代码和数据,必须通过严格的接口控制。
-
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
-
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
3.1.1.2-封装的优点
-
良好的封装能够减少耦合。
-
类内部的结构可以自由修改。
-
可以对成员变量进行更精确的控制。
-
隐藏信息,实现细节。
3.1.2-封装的代码详解
-
修改属性的可见性来限制对属性的访问(一般限制为private)例如:
public class Person {
//使用private将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
private String name;
private int age;
}
-
对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问 例如:
package Target;
public class Encapsulation {
private String name;
private int age;
public Encapsulation() {
}
public Encapsulation(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
注意事项:
-
get方法获取数据,set方法输出数据
-
采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
-
实例;
-
封装类
package Target;
public class Encapsulation {
private String name;
private int age;
public Encapsulation() {
}
public Encapsulation(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
-
实现类
package Target;
public class Application {
public static void main(String[] args) {
//观察输出什么
Encapsulation encapsulation = new Encapsulation("laizimoxia", 21);
encapsulation.setName("moxia");
encapsulation.setAge(20);
System.out.println("姓名"+ encapsulation.getName() +
"年龄"+ encapsulation.getAge());
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/e2174d35e2754cdd5a1bf112f3762410.png)
注:大家可以发现他没有输出 laizimoxia 而是输出moxia,这是因为属性私有的原因,只有通过get,set方法才能进行输出,输入。
3.2-继承
3.2.1-初识继承
3.2.1.1-什么是继承
-
继承是Java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
-
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
3.2.1.2-继承的关键字
-
extends关键字:在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
-
implements关键字:使用 implements 关键字可以变相的使Java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)
3.2.1.3-继承的特性
-
子类拥有父类非 private 的属性、方法。
-
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
-
子类可以用自己的方式实现父类的方法。
-
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
-
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
3.2.1.4-继承在生活中实例
![](https://img-blog.csdnimg.cn/img_convert/580b4e340c1ac0ab6dc73ee9243b23d9.png)
3.2.1.5-继承的格式
class 父类 {
}
class 子类 extends 父类 {
}
3.2.2-方法重写
-
指两个方法的返回值、方法名、参数的类型和个数相同** (子类重写父类的方法)。
-
方法的重写,不能发生在同类中,只能发生在子类中。
-
若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。
public class Dom2{
public void eat(){
System.out.println( "正在吃");
}
}
//继Dom2的方法
class Dom extends Dom2{
//方法重写
@Override
public void eat() {
System.out.println("zhengzaich");
}
3.2.3-继承的代码详解
-
继承属性
public class Person {//父类
public Person(String name, int age) {
}
public Person(String name, int age, String sex) {
}
}
//Sstudent为子类继承Person
class Student extends Person {
public Student(String name, int age, String birth) {
super(name, age); // 调用父类中含有2个参数的构造方法
}
public Student(String name, int age, String sex, String birth) {
super(name, age, sex); // 调用父类中含有3个参数的构造方法
}
}
-
继承方法
package Target;
public class Dom2{
public void eat(){
System.out.println( "正在吃");
}
}
class Dom extends Dom2{//继Dom2的方法
@Override
public void eat() {//方法重写
System.out.println("zhengzaich");
}
void eatTest(){
super.eat();//使用Dom2的方法
this.eat();//使用自己的方法
}
}
class Test{
public static void main(String[] args) {
Dom2 dom2 = new Dom2();
dom2.eat();
Dom dom = new Dom();
dom.eatTest();
}
}
输出结果:
3.3-多态
3.3.1-初识多态
-
动态编译 类型:可扩展性变得更强
-
同一方法可以根据发送对象的不同而采用多种不同的行为方式。
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
-
多态分为 向上转型和向下转型。
-
多态存在的条件:
-
有继承关系。
-
子类重写分类方法。
-
父类引用指向子类对象。
注:多态是方法的多态,属性没有多态性。
向下转型时候一定要经过instanceof关键字进行判断
3.3.2-多态的代码详解
class Shape {//shape父类,可以有多个子类,
void draw() {}
}
class Circle extends Shape {//子类只能由一个父类,并重写父类方法
void draw() {
System.out.println("Circle.draw()");
}
}
class Square extends Shape {//子类只能由一个父类,并重写父类方法
void draw() {
System.out.println("Square.draw()");
}
}
class Triangle extends Shape {//子类只能由一个父类,并重写父类方法
void draw() {
System.out.println("Triangle.draw()");
}
}
3.3.3-向上转型
格式:
父类名称 对象名 = new 子类名称();
含义:
右侧创造一个子类对象,把他当作父类来看待使用。
注意事项:
向上转型一定安全,从小范围转到大范围。
3.3.4-向下转型
格式:
子类名称 对象名 = (子类名称)父类对象;
含义:
将父类对象【还原】成为原来的子类对象;
注意事项:
向下转型时候一定要经过instanceof关键字进行判断
4-super关键字
4.1-初识super关键字:
-
由于子类不能继承父类的构造方法,因此,如果要调用父类的构造方法,可以使用 super 关键字。super 可以用来访问父类的构造方法、普通方法和属性。
-
在子类的构造方法中显式的调用父类构造方法
-
访问父类的成员方法和变量.
4.2-super关键字代码详解:
4.2.1-super访问父类成员
super.类名;
4.2.2-super调用成员属性
package Target;
public class Application {
public static void main(String args[]) {
Student student = new Student();
student.test();
}
}
class Person {
int age = 12;
}
class Student extends Person {
int age = 18;
void test() {
System.out.println("学生年龄:" + super.age);
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/2759bff8c609df4cfd0437387d84d82c.png)
4.2.3-super调用成员方法
package Target;
public class Application {
public static void main(String args[]) {
Student student = new Student();
student.nameTest();
}
}
class Person {
void name() {
System.out.println("person");
}
}
class Student extends Person {
void name() {
System.out.println("student");
}
void nameTest() {
name();
super.name();
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/47b7099d9363aeb1733c84eb5e4231ad.png)
5-this关键字:
5.1-初识this关键字
-
this 关键字是Java常用的关键字,可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,或者在需要当前类型对象引用时使用。
-
大部分时候,普通方法访问其他方法、成员变量时无须使用 this 前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用 this 前缀。
-
this关键字的使用:
-
this.属性名
-
this.方法名
-
this( )访问构造方法
5.2-this关键字的代码详解
5.2.1-this.属性名
package Target;
public class Application {
public static void main(String args[]) {
Student student = new Student();
student.test();
}
}class Person {
int age = 12;
}
class Student extends Person {
int age = 18;
void test() {
System.out.println("学生年龄:" + this.age);
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/9d58303329375fd2562b8dc0280a683b.png)
5.2.2-this.方法名
package Target;
public class Dom2{
public void eat(){
System.out.println( "正在吃");
}
}
class Dom extends Dom2{
@Override
public void eat() {
System.out.println("this关键字");
}
void eatTest(){
super.eat();
this.eat();
}
}
class Test{
public static void main(String[] args) {
Dom2 dom2 = new Dom2();
dom2.eat();
Dom dom = new Dom();
dom.eatTest();
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/c8e398406e8d8642afa76d30b20c332e.png)
5.2.3-this( )访问构造方法
package Target;
public class Dom3 {
String name;
// 无参构造方法(没有参数的构造方法)
public Dom3() {
this("魔匣");
}
// 有参构造方法
public Dom3(String name) {
this.name = name;
}
// 输出name
public void print() {
System.out.println("姓名:" + name);
}
public static void main(String[] args) {
Dom3 dom3 = new Dom3();
dom3.print();
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/d8b99f8fbdb302491969346617edb103.png)
6-final 关键字
6.1-初识final关键字
-
final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
-
final 含义为 "最终的"。
-
使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写;
6.2-final关键字的代码详解
-
声明类:
final class 类名 {//类体}
-
声明方法:
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
注:final 定义的类,其中的属性、方法不是 final 的。
7-抽象类
7.1-初识抽象类
-
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
-
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
-
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
-
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
-
在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
7.2-抽象类的代码详解
public abstract class Action{
//约束
//abstract 抽象方法,只有方法名字,没有方法实现。
public absteact void doSomething();
//抽象类的所有方法,继承了它的子类,都必须实现他的方法
}
8-接口
8.1-初识接口
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有!
-
接口:只有规范
-
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
-
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念:
-
类描述对象的属性和方法。
-
接口则包含类要实现的方法。
-
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
-
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
8.2接口与类的区别:
-
接口不能用于实例化对象。
-
接口没有构造方法。
-
接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
-
接口不能包含成员变量,除了 static 和 final 变量。
-
接口不是被类继承了,而是要被类实现。
-
接口支持多继承。
8.3抽象类和接口的区别:
-
抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
-
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
-
.接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
-
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
8.4-接口特性
-
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
-
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
-
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
8.5-接口的代码详解
8.5.1-接口的声明语法格式如下:
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
8.5.2--接口声明实例:
package Target;
interface Dom4{
public void eat();
public void cat();
}
8.5.3-接口的实现:
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
8.5.4-接口实现的实例;
package Target;
public class Dom5 implements Dom4{
@Override
public void eat() {
System.out.println("Dom5");
}
@Override
public void cat() {
System.out.println("吃鱼");
}
public static void main(String[] args) {
Dom5 dom5 = new Dom5();
dom5.eat();
dom5.cat();
}
}
输出结果:
![](https://img-blog.csdnimg.cn/img_convert/a5255b9aa4dd51353b1c2bfe36079c52.png)
8.5.5-接口的继承:
package Target;
interface Dom4{
public void eatDom4();
public void catDom4();
}
//接口的继承
interface Football extends Dom4
{
public void eatFootball();
public void catFootball();
}
8.5.6-接口的多继承
package Target;
interface Dom4{
public void eatDom4();
public void catDom4();
}
interface Hockey
{
public void eatHocker();
public void catHocker();
}
//接口的多继承
interface Football extends Dom4,Hockey
{
public void eatFootball();
public void catFootball();
}
9-内部类
9.1-初识内部类
-
Java 一个类中可以嵌套另外一个类,语法格式如下:
class Outer { // 外部类
// ...
class Nested { // 嵌套类,或称为内部类
// ...
}
}
-
要访问内部类,可以通过创建外部类的对象,然后创建内部类的对象来实现。
-
嵌套类有两种类型:
-
非静态内部类
-
静态内部类
9.2-非静态内部类
非静态内部类是一个类中嵌套着另外一个类。 它有访问外部类成员的权限, 通常被称为内部类。
由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现。
class Outer {
int x = 10;
class Inner {
int y = 5;
}
}
public class My {
public static void main(String[] args) {
Outer myOuter = new Outer();
Outer.Inner myInner = myOuter.new Inner();
System.out.println(myInner.y + myOuter.x);
}
}
以下实例执行输出结果为:
15
9.3-静态内部类
class Outer {
int x = 10;
static class Inner {
int y = 5;
}
}
public class MyMain {
public static void main(String[] args) {
Outer.Inner myInner = new Outer.Inner();
System.out.println(myInner.y);
}
}
以下实例执行输出结果为:
5
9.4-从内部类访问外部类成员
class Outer {
int x = 10;
class Inner {
public int myInnerMethod() {
return x;
}
}
}
public class MyMain {
public static void main(String[] args) {
Outer myOuter = new Outer();
Outer.Inner myInner = myOuter.new Inner();
System.out.println(myInner.myInnerMethod());
}
}
以下实例执行输出结果为:
10