标签:Java 子类 void public 面向对象 父类 方法 class
Java面向对象
面向过程与面向对象:
-
面向过程
- 步骤清晰,一步一步按顺序执行。
- 性能比面向对象好,因为类调用时需要实例化,开销比较大,比较消耗资源。
- 适合解决一些简单的问题。
-
面向对象
- 一种分类的思维模式,看哪些问题需要分类,再对这些分类进行单独思考,最后进行分类面向对象执行。
- 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护 。
- 适合解决处理复杂的问题。
*** : 简单来说面向对象是一种抽象的思维,将问题看成抽象成类,在类里面进行面向过程的步骤执行。
面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据
类与对象的关系:
-
类是一种抽象的数据类型,是对某一事物的定义,不能代表任一具体事物。
- 例如:Person类、Pet类、Car类等,都是一个具有现实意义的统称。
-
对象是抽象概念的具体实现。
- 小明就是Person类中的一个具体实例,Ford是Car的一个具体实例。
- 能够体现出特点,展现出功能的是具体实例,而不是一个抽象的概念。
创建和初始化对象:
通过new关键字来创建初始化一个对象:
public class Application {
public static void main(String[] args) {
Obj1 obj1 = new Obj1(); //通过new创建一个对象
obj1.run(); //引用对象里面的方法
}
}
class Obj1 { //定义一个类
String name = "鸟";
String t = "飞";
public void run(){ //在类中定义一个方法
System.out.println(name + "在" + t);
}
}
构造器:
类中的构造器也称为构造方法,实在进行创建对象的时候必须调用的。构造器有一下特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
注意:1)new 的本质实在调用构造方法。
2)初始化对象的值。
public class Application {
public static void main(String[] args) {
Obj2 obj2 = new Obj2(); //创建此对象,必须要存在无参构造器
Obj2 obj21 = new Obj2("VXL", 18);
}
}
class Obj2 {
String name;
int age;
//定义一个无参构造器(一般无定义有参构造器,类会自动生成无参构造器)
public Obj2() {
}
//定义一个有参构造器
public Obj2(String name, int age) {
this.name = name;
this.age = age;
System.out.println(name + " " + age); //输出 VXL 18
}
}
封装
封装:禁止直接访问一个对象中数据的实际表示,通过操作接口来访问,称为信息隐藏。
可理解为:属性是私有的,可通过get、set方法来调用封装的数据。
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 提高系统的可维护性
public class Application {
public static void main(String[] args) {
Obj3 a = new Obj3();
a.setName("VXL"); //调用set方法并赋值
String name = a.getName(); //调用get方法传值
System.out.println(name); //输出VXL
}
}
class Obj3 {
//属性都私有;不可直接调用
private String name;
//提供一些可以操作这个属性的方法;
public String getName() { //get: 获得这个数据;
return name;
}
public void setName(String name) { //set: 给这个数据设置值
this.name = name;
}
}
继承
- 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
- Java中只有单继承,没有多继承。
- 继承是类与类之间的一种关系。
- 继承关系的两个类,一个为子类,一个为父类。子类继承父类,使用关键字
extends
来表示。 - 子类和父类之间,从意义上讲应该具有“is a”的关系。
- 子类继承父类后,子类就拥有该父类的所有public方法和属性,但不会继承private方法。
public class Objext { //定义父类,父类里面有方法属性
String name = "VXL";
public void run() {
System.out.println(name + "开始跑步!");
}
}
public class Objex1 extends Objext { //定义一个子类,继承父类里面的所有方法属性
}
public class Application {
public static void main(String[] args) {
Objex1 a = new Objex1(); //使用new创建一个子类对象
a.run(); //输出父类中所有方法属性
}
}
super关键字
super
与this
:
this
:本类的构造,本身调用者这个对象,无继承的情况下直接使用。
super
:父类的构造,是定向到父类的参数,直接调用父类的方法属性。只能在继承情况下才能使用。
public class Application {
public static void main(String[] args) {
Objex1 a = new Objex1();
a.test();
//子类输出的语句
//子类输出的语句
//父类的输出语句
}
}
public class Objext { //父类
String name = "父类";
public void print() {
System.out.println("父类的输出语句");
}
}
public class Objex1 extends Objext { //子类
public void print() {
System.out.println("子类输出的语句");
}
public void test() {
print();
this.print(); //指向Objex1里面的print
super.print(); //执行Objext里面的print
}
}
注意:在父类中如果定义了无参构造方法,那么子类也会默认继承该方法。如果定义了有参构造方法,子类就必须调用父类的有参才可以继承。
//无参构造方法:
public class Application {
public static void main(String[] args) {
Objex1 a = new Objex1();
//父类的无参构造方法
//子类的无参构造方法
}
}
public class Objext { //父类
public Objext() {
System.out.println("父类的无参构造方法");
}
}
public class Objex1 extends Objext { //子类
public Objex1() {
super(); //该super一般默认会给的,不用直接写上去
System.out.println("子类的无参构造方法");
}
}
有参构造方法:
public class Application {
public static void main(String[] args) {
Objex1 a = new Objex1();
//父类的有参构造方法
//子类的有参构造方法
}
}
public class Objext { //父类
public Objext(String name) { //定义有参构造方法
System.out.println("父类的有参构造方法");
}
}
public class Objex1 extends Objext { //子类
public Objex1() {
super("name"); //super调用父类有参参数,不能省略
System.out.println("子类的有参构造方法");
}
}
super注意点: 1) super
调用父类的构造方法,且必须在构造方法的第一个
2) super
必须只能出现在子类的方法或者构造方法中
3)super
和this
不能同时调用构造方法,而在普通方法中则可以。
final关键字:
final
关键字可用于修饰类、变量和方法,它有“无法改变”或者“最终”的含义,因此被final修饰的类、变量和方法将具有以下特性:final
修饰的类不能被继承。final
修饰的方法不能被子类重写。final
修饰的变量(成员变量和局部变量)是常量,只能赋值一次。
所以,Java中的类被final关键字修饰后,该类将不可以被继承,也就是不能够派生子类。
当一个类的方法被final关键字修饰后,这个类的子类将不能重写该方法。
final修饰的变量一旦被赋值,其值不能改变。如果再次对该变量进行赋值,则程序会在编译时报错。
方法重写/覆盖:
--- 为什么需要重写?----->父类的功能,子类不一定需要或者不一定满足。
方法覆盖发生在继承里,子类根据需要重写继承的方法,用父类的方法名重写了一个新的方法。
需要覆盖的方法要和父类方法具有完全相同的方法名,返回值,参数列表。
简单来说,就是new定义对象的左边是用哪个类就调用哪个类的方法进行重写;
public class Application {
public static void main(String[] args) {
Objex3 a = new Objex3();
a.test(); //子类
Objex2 b = new Objex3(); //父类的引用指向了子类,子类重写了父类的方法,改变父类方法属性
b.test(); //子类
}
}
public class Objex2{
public void test() { //父类方法
System.out.println("父类");
}
}
public class Objex3 extends Objex2{
public void test() { //方法重写
System.out.println("子类");
}
}
注意:1) 重写是重写非静态方法的,静态方法不能被重写。
2)重写的方法只能是public修饰符,其他的都不可以。
3)子类重写父类的方法,且和父类方法具有完全相同的方法名,返回值,参数列表。方法体可以不同。
多态:
- 同一个方法可以根据发送对象的不同而采取多种不同的行为方式。
- 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
注意:1)多态是方法的多态,属性没有多态。
2)父类与子类直接有关联,存在继承关系,方法需要重写,父类引用指向子类对象。
3)用static、final、private 修饰符的没有多态。
public class Application { //左边是用哪个类就调用哪个类的方法,主要看new的左边。
public static void main(String[] args) {
Student s = new Student(); //定向到Student子类
Person p = new Student(); //定向到Person父类
s.say(); //hello!
p.say(); //方法重写后,输出hello!
s.run(); // 子类独有的方法,输出running!
p.run(); // error!父类不能调用子类独有的方法
}
}
public class Person { //父类
public void say() {
System.out.println("hi!");
}
}
public class Student extends Person { //子类
@Override //父类方法重写
public void say() {
System.out.println("hello!");
}
public void run() { //子类独有的类
System.out.println("running!");
}
}
instanceof与类型转换:
instanceof
可用与判断父类与子类间是否存在关系,该结果为Boolean值。
格式:Bool = (X instanceof Y)
;
判断其能不能通过,就可以确定X,Y之间有没有父子关系了。
public class Application { //判断两者之间是否具有父子关系
public static void main(String[] args) {
Object o = new Student();
System.out.println((o instanceof Student)); //true
System.out.println((o instanceof Person)); //true
System.out.println((o instanceof Teacher)); //false
System.out.println((o instanceof String)); //false
Person p = new Student();
System.out.println((p instanceof Student)); //true
System.out.println((p instanceof Person)); //true
System.out.println((p instanceof Teacher)); //false
}
}
public class Person {}
public class Student extends Person {} //上面定义的是Student实例
public class Teacher extends Person {} //Teacher类不属于Student实例里面的
类型转换:父类与子类之间的转换。
1)父类引用指向子类的对象。
2)子类转换为父类,向上转型。不用进行强制转换
3)父类转换为子类,向下转型。需要进行强制转换
public class Application {
public static void main(String[] args) {
Person p = new Student();
p.say(); //hello!
((Student)p).run(); //父类调用子类独有的类需要进行强制转换,不然会出错。
}
}
public class Person { //父类
public void say() {
System.out.println("hi!");
}
}
public class Student extends Person { //子类
@Override //父类方法重写
public void say() {
System.out.println("hello!");
}
public void run() { //子类独有的类
System.out.println("running!");
}
}
static关键字:
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。
注意:在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用,但是在非静态成员方法中是可以访问静态成员方法/变量的。
1)静态不能访问非静态; 2)非静态可以访问静态;
使用方法:
1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来。
2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来。
public class Person { //static常量与方法的使用方法都一样
private String name; //非静态常量
private static int age; //静态常量
public static void main(String[] args) {
Person person = new Person(); //调用非静态需要new一个对象
String name = person.name;
int age = Person.age; //调用静态不需要new一个对象,只需要 类名.常量 就可以。
}
}
抽象类:abstract
Java允许在定义方法时不写方法体,不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰。
格式:abstract void shout();
定义一个抽象方法。
抽象类的特性:
-
包含抽象方法的类必须声明为抽象类,但抽象类可以不包含任何抽象方法,只需使用abstract关键字来修饰即可。抽象类可以写普通方法,普通类不能写抽象方法。
-
抽象类是不可以被实例化的,因为抽象类中有可能包含抽象方法,抽象方法是没有方法体的,不可以被调用。
不能new实例。
-
如果想调用抽象类中定义的方法,则需要创建一个子类,在子类中将抽象类中的抽象方法进行重写实现。
public abstract class Abstract { //抽象类
public abstract void run(); //抽象方法
public void eat() { //普通方法
System.out.println("eat!");
}
}
接口:interface
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!接口自己无法写方法。(需要有具体的实现类implement)
接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象。在定义接口时,需要使用interface关键字来声明,一个类只能有一个父类,而一个类可以实现多个接口。其语法格式如下:
//一个接口可以有多个父接口,他们之间用逗号隔开。
[public] interface 接口名 [extends 接口1, extends 接口2] {
[public] [static] [final] 数据类型 常量名 = 常量值;
[public] [abstract] 返回值 抽象方法名(参数列表);
}
类实现接口:由于接口中的方法都是抽象方法,因此不能通过实例化对象的方式来调用接口中的方法。此时需要定义一个类,并使用implements关键字实现接口中所有的方法,实现接口,必须重写接口方法。格式:
[修饰符] class <类名> [extends <超类名>] [implement <接口1 >,<接口2>]....]
public interface Inter { //定义一个接口
void run();
void eat();
}
public class Inter1 implements Inter{ //定义一个class去重写调用接口里面的方法
@Override
public void run() {
System.out.println("run");
}
public class Application {
public static void main(String[] args) {
Inter1 inter1 = new Inter1(); //创建一个调用接口的类的新对象
inter1.run(); //输出run
}
}
注意:
- 接口中的方法都是抽象的,不能实例化对象。
- 接口中的属性只能是常量。
- 当一个类实现接口时,如果这个类是抽象类,则实现接口中的部分方法即可,否则需要实现接口中的所有方法。
- 一个类通过implements关键字实现接口时,可以实现多个接口,被实现的多个接口之间要用逗号隔开。
- 当只有一个接口的方法叫做函数式方法,可以使用lambda表达式直接简化使用。
成员内部类:
在Java中,允许在一个类的内部定义类,这样的类称作内部类,这个内部类所在的类称作外部类。根据内部类的位置、修饰符和定义的方式可分为:成员内部类、静态内部类、方法内部类。
主要还有的就是,可在内部类获得外部类的私有属性。
-
匿名对象的使用:
new 类名称().该类的方法();
--->不用将实例保存到变量中 -
创建内部类对象的具体语法格式如下:
外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
public class Application {
public static void main(String[] args) {
//通过创建外部类再来实例化内部类
new Inter1().ex(); //匿名对象的使用,没有类的名字。
Inter1.Inter2 b = new Inter1().new Inter2(); //引用内部类
b.ex1(); //内部类 VXL
}
}
public class Inter1 { //第一个类
private String name = " VXL"; //定义外部类的私有属性
public void ex() {
System.out.println("外部类");
}
public class Inter2 { //在第一个类的内部再生成一个类(内部类)
public void ex1() {
System.out.println("内部类");
//可在内部类获得外部类的私有属性
System.out.println(name);
}
}
}
标签:Java,子类,void,public,面向对象,父类,方法,class 来源: https://www.cnblogs.com/vxzx/p/14552872.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。