You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ke...@apache.org on 2023/09/06 20:33:26 UTC

[arrow] branch main updated: GH-37591: [MATLAB] Make `arrow.type.Type` inherit from `matlab.mixin.Heterogeneous` (#37593)

This is an automated email from the ASF dual-hosted git repository.

kevingurney pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new f7b6ddbe87 GH-37591: [MATLAB] Make `arrow.type.Type` inherit from `matlab.mixin.Heterogeneous` (#37593)
f7b6ddbe87 is described below

commit f7b6ddbe8787fe62f5bde5cf9e686380c60adc40
Author: sgilmore10 <74...@users.noreply.github.com>
AuthorDate: Wed Sep 6 16:33:07 2023 -0400

    GH-37591: [MATLAB] Make `arrow.type.Type` inherit from `matlab.mixin.Heterogeneous` (#37593)
    
    
    
    ### Rationale for this change
    
    We should modify `arrow.type.Type` to inherit from `matlab.mixin.Heterogeneous` so that it's possible to create a nonscalar array containing different concrete subclasses of `arrow.type.Type`.
    
    **Example**
    ```matlab
    >> float32Type = arrow.float32();
    >> timestampType = arrow.timestamp(TimeZone="Pacific/Fiji");
    >> typeArray = [float32Type timestampType]
    
    typeArray =
    
      1×2 heterogeneous FixedWidthType (Float32Type, TimestampType) array with properties:
    
        ID
    ```
    
    Currently, running the example above results in an error:
    
    ```matlab
    >> float32Type = arrow.float32();
    >> timestampType = arrow.timestamp(TimeZone="Pacific/Fiji");
    >> typeArray = [float32Type timestampType]
    Error using horzcat
    The following error occurred converting from arrow.type.TimestampType to arrow.type.Float32Type:
    Invalid argument at position 1. Value must be of type libmexclass.proxy.Proxy or be convertible to libmexclass.proxy.Proxy.
    ```
    
    ### What changes are included in this PR?
    
    1. Updated `arrow.type.Type` to inherit from `matlab.mixin.Heterogeneous`. Previously, it only inherited from `matlab.mixin.CustomDisplay`.
    2. Because `arrow.type.Type` is now `heterogeneous`, its subclasses cannot override the protected method `getPropertyGroups` - which is inherited from `matlab.mixin.CustomDisplay`. This method must be `Sealed` and defined on `Type` because only `Sealed` methods can be called on nonscalar `heterogeneous` arrays. To get around this limitation, I defined a new abstract template method called `getDisplayPropertyGroups`, which `getPropertyGroups` invokes if the array is either scalar or no [...]
    
    **Displaying a nonscalar *heterogeneous* `arrow.type.Type`**
    
    ```matlab
    >> float32Type = arrow.timestamp(TimeUnit="Second");
    >> timestampType = arrow.timestamp(TimeZone="Pacific/Fiji");
    >> typeArray = [float32Type timestampType]
    
    typeArray =
    
      1×2 heterogeneous FixedWidthType (Float32Type, TimestampType) array with properties:
    
        ID
    ```
    
    **Displaying a nonscalar *homogeneous* `arrow.type.Type`**
    
    ```matlab
    >> timestampType1 = arrow.timestamp(TimeUnit="Second");
    >> timestampType2 = arrow.timestamp(TimeZone="Pacific/Fiji");
    >> typeArray = [timestampType1 timestampType2]
    
    typeArray =
    
      1×2 TimestampType array with properties:
    
        ID
        TimeUnit
        TimeZone
    ```
    
    ### Are these changes tested?
    
    Yes
    
    1. Added a new test class in `test/arrow/type` called `tDisplay.m`
    2. Added display unit tests for all concrete subclasses of `arrow.type.Type` if they did not already exist.
    3. Added a new test class in `test/arrow/type` called `tIsEqual.m`. This class contains unit tests verifying the `isequal` method of `arrow.type.Type` behaves as expected when called on heterogeneous arrays.
    
    ### Are there any user-facing changes?
    
    Yes. Users can now create nonscalar  arrays with different concrete subclasses of `arrow.type.Type`.
    
    ### Future Directions
    
    1. Move all display unit tests to `tDisplay.m`
    2. Add an `arrow.type.NumericType` class from which all numeric types inherit. This class will define `getDisplayPropertyGroups` for all numeric types.
    
    * Closes: #37591
    
    Authored-by: Sarah Gilmore <sg...@mathworks.com>
    Signed-off-by: Kevin Gurney <kg...@mathworks.com>
---
 matlab/src/matlab/+arrow/+type/BooleanType.m   |   7 +
 matlab/src/matlab/+arrow/+type/DateType.m      |   4 +-
 matlab/src/matlab/+arrow/+type/Float32Type.m   |   7 +
 matlab/src/matlab/+arrow/+type/Float64Type.m   |   7 +
 matlab/src/matlab/+arrow/+type/Int16Type.m     |   7 +
 matlab/src/matlab/+arrow/+type/Int32Type.m     |   7 +
 matlab/src/matlab/+arrow/+type/Int64Type.m     |   7 +
 matlab/src/matlab/+arrow/+type/Int8Type.m      |   7 +
 matlab/src/matlab/+arrow/+type/StringType.m    |   9 +-
 matlab/src/matlab/+arrow/+type/TimeType.m      |   4 +-
 matlab/src/matlab/+arrow/+type/TimestampType.m |   6 +-
 matlab/src/matlab/+arrow/+type/Type.m          |  56 +++++-
 matlab/src/matlab/+arrow/+type/UInt16Type.m    |   8 +
 matlab/src/matlab/+arrow/+type/UInt32Type.m    |   8 +
 matlab/src/matlab/+arrow/+type/UInt64Type.m    |   7 +
 matlab/src/matlab/+arrow/+type/UInt8Type.m     |   7 +
 matlab/test/arrow/type/tDate32Type.m           |  22 ---
 matlab/test/arrow/type/tDate64Type.m           |  22 ---
 matlab/test/arrow/type/tIsEqual.m              |  52 +++++
 matlab/test/arrow/type/tTime32Type.m           |  22 ---
 matlab/test/arrow/type/tTime64Type.m           |  22 ---
 matlab/test/arrow/type/tTimestampType.m        |  23 ---
 matlab/test/arrow/type/tTypeDisplay.m          | 256 +++++++++++++++++++++++++
 23 files changed, 452 insertions(+), 125 deletions(-)

diff --git a/matlab/src/matlab/+arrow/+type/BooleanType.m b/matlab/src/matlab/+arrow/+type/BooleanType.m
index 6afa00e925..197ab51583 100644
--- a/matlab/src/matlab/+arrow/+type/BooleanType.m
+++ b/matlab/src/matlab/+arrow/+type/BooleanType.m
@@ -25,4 +25,11 @@ classdef BooleanType < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/DateType.m b/matlab/src/matlab/+arrow/+type/DateType.m
index f8a3966602..ac6ece47ce 100644
--- a/matlab/src/matlab/+arrow/+type/DateType.m
+++ b/matlab/src/matlab/+arrow/+type/DateType.m
@@ -36,9 +36,9 @@ classdef DateType < arrow.type.TemporalType
     end
 
     methods (Access=protected)
-        function group = getPropertyGroups(~)
+        function groups = getDisplayPropertyGroups(~)
             targets = ["ID" "DateUnit"];
-            group = matlab.mixin.util.PropertyGroup(targets);
+            groups = matlab.mixin.util.PropertyGroup(targets);
         end
     end
 
diff --git a/matlab/src/matlab/+arrow/+type/Float32Type.m b/matlab/src/matlab/+arrow/+type/Float32Type.m
index df5fa1ce84..98c9f5fd79 100644
--- a/matlab/src/matlab/+arrow/+type/Float32Type.m
+++ b/matlab/src/matlab/+arrow/+type/Float32Type.m
@@ -25,4 +25,11 @@ classdef Float32Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Float64Type.m b/matlab/src/matlab/+arrow/+type/Float64Type.m
index ba93265ebc..634e7d1a5c 100644
--- a/matlab/src/matlab/+arrow/+type/Float64Type.m
+++ b/matlab/src/matlab/+arrow/+type/Float64Type.m
@@ -25,4 +25,11 @@ classdef Float64Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Int16Type.m b/matlab/src/matlab/+arrow/+type/Int16Type.m
index c16d3fd5ca..ca59f1c077 100644
--- a/matlab/src/matlab/+arrow/+type/Int16Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int16Type.m
@@ -25,5 +25,12 @@ classdef Int16Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
 
diff --git a/matlab/src/matlab/+arrow/+type/Int32Type.m b/matlab/src/matlab/+arrow/+type/Int32Type.m
index 786697bf11..68036d6485 100644
--- a/matlab/src/matlab/+arrow/+type/Int32Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int32Type.m
@@ -25,5 +25,12 @@ classdef Int32Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
 
diff --git a/matlab/src/matlab/+arrow/+type/Int64Type.m b/matlab/src/matlab/+arrow/+type/Int64Type.m
index bf6c71d622..d5bd7ff3a5 100644
--- a/matlab/src/matlab/+arrow/+type/Int64Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int64Type.m
@@ -25,4 +25,11 @@ classdef Int64Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Int8Type.m b/matlab/src/matlab/+arrow/+type/Int8Type.m
index b28785f876..5df75afe76 100644
--- a/matlab/src/matlab/+arrow/+type/Int8Type.m
+++ b/matlab/src/matlab/+arrow/+type/Int8Type.m
@@ -25,5 +25,12 @@ classdef Int8Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
 
diff --git a/matlab/src/matlab/+arrow/+type/StringType.m b/matlab/src/matlab/+arrow/+type/StringType.m
index c269bfa6db..53c73b3e33 100644
--- a/matlab/src/matlab/+arrow/+type/StringType.m
+++ b/matlab/src/matlab/+arrow/+type/StringType.m
@@ -24,6 +24,13 @@ classdef StringType < arrow.type.Type
             import arrow.internal.proxy.validate
             obj@arrow.type.Type(proxy);
         end
-   end
+    end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
 
diff --git a/matlab/src/matlab/+arrow/+type/TimeType.m b/matlab/src/matlab/+arrow/+type/TimeType.m
index 59d9387889..a0f8beb704 100644
--- a/matlab/src/matlab/+arrow/+type/TimeType.m
+++ b/matlab/src/matlab/+arrow/+type/TimeType.m
@@ -36,9 +36,9 @@ classdef TimeType < arrow.type.TemporalType
     end
 
     methods (Access=protected)
-        function group = getPropertyGroups(~)
+        function groups = getDisplayPropertyGroups(~)
             targets = ["ID" "TimeUnit"];
-            group = matlab.mixin.util.PropertyGroup(targets);
+            groups = matlab.mixin.util.PropertyGroup(targets);
         end
     end
 
diff --git a/matlab/src/matlab/+arrow/+type/TimestampType.m b/matlab/src/matlab/+arrow/+type/TimestampType.m
index cb47743148..07e61f9570 100644
--- a/matlab/src/matlab/+arrow/+type/TimestampType.m
+++ b/matlab/src/matlab/+arrow/+type/TimestampType.m
@@ -42,9 +42,9 @@ classdef TimestampType < arrow.type.TemporalType
     end
 
     methods (Access=protected)
-        function group = getPropertyGroups(~)
-          targets = ["ID" "TimeUnit" "TimeZone"];
-          group = matlab.mixin.util.PropertyGroup(targets);
+        function groups = getDisplayPropertyGroups(~)
+            targets = ["ID" "TimeUnit" "TimeZone"];
+            groups = matlab.mixin.util.PropertyGroup(targets);
         end
     end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/Type.m b/matlab/src/matlab/+arrow/+type/Type.m
index cc2da1403b..8f4ce4dd6c 100644
--- a/matlab/src/matlab/+arrow/+type/Type.m
+++ b/matlab/src/matlab/+arrow/+type/Type.m
@@ -13,7 +13,8 @@
 % implied.  See the License for the specific language governing
 % permissions and limitations under the License.
 
-classdef (Abstract) Type < matlab.mixin.CustomDisplay
+classdef (Abstract) Type < matlab.mixin.CustomDisplay & ...
+                           matlab.mixin.Heterogeneous
 %TYPE Abstract type class. 
 
     properties (Dependent, GetAccess=public, SetAccess=private)
@@ -42,14 +43,57 @@ classdef (Abstract) Type < matlab.mixin.CustomDisplay
         end
     end
 
-    methods (Access=protected)
-        function propgrp = getPropertyGroups(~)
-          proplist = {'ID'};
-          propgrp = matlab.mixin.util.PropertyGroup(proplist);
+    methods(Access = protected)
+        groups = getDisplayPropertyGroups(obj)
+    end
+
+    methods (Sealed, Access = protected)
+        function header = getHeader(obj)
+            header = getHeader@matlab.mixin.CustomDisplay(obj);
+        end
+ 
+        function groups = getPropertyGroups(obj)
+            if isscalar(obj)
+               groups = getDisplayPropertyGroups(obj);
+            else
+                % Check if every type in the array has the same class type.
+                % If so, call getDisplayPropertyGroups() so that all
+                % properties assoicated with that class are displayed.
+                classnames = arrayfun(@(type) string(class(type)), obj);
+                if numel(unique(classnames)) == 1
+                    groups = getDisplayPropertyGroups(obj(1));
+                else
+                    % If the array is heterogeneous, just display ID, which
+                    % is the only property shared by all concrete
+                    % subclasses of arrow.type.Type.
+                    proplist = "ID";
+                    groups = matlab.mixin.util.PropertyGroup(proplist);
+                end
+            end
+        end
+ 
+        function footer = getFooter(obj)
+            footer = getFooter@matlab.mixin.CustomDisplay(obj);
+        end
+ 
+        function displayNonScalarObject(obj)
+            displayNonScalarObject@matlab.mixin.CustomDisplay(obj);
+        end
+
+        function displayScalarObject(obj)
+            displayScalarObject@matlab.mixin.CustomDisplay(obj)
+        end
+
+        function displayEmptyObject(obj)
+            displayEmptyObject@matlab.mixin.CustomDisplay(obj);
+        end
+
+        function displayScalarHandleToDeletedObject(obj)
+            displayScalarHandleToDeletedObject@matlab.mixin.CustomDisplay(obj);
         end
     end
 
-    methods
+    methods (Sealed)
         function tf = isequal(obj, varargin)
 
             narginchk(2, inf);
diff --git a/matlab/src/matlab/+arrow/+type/UInt16Type.m b/matlab/src/matlab/+arrow/+type/UInt16Type.m
index 3198b78671..d7600c982b 100644
--- a/matlab/src/matlab/+arrow/+type/UInt16Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt16Type.m
@@ -25,4 +25,12 @@ classdef UInt16Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/UInt32Type.m b/matlab/src/matlab/+arrow/+type/UInt32Type.m
index 53e60e4e34..e16699cba5 100644
--- a/matlab/src/matlab/+arrow/+type/UInt32Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt32Type.m
@@ -25,4 +25,12 @@ classdef UInt32Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/UInt64Type.m b/matlab/src/matlab/+arrow/+type/UInt64Type.m
index f8512ec594..c190f252ab 100644
--- a/matlab/src/matlab/+arrow/+type/UInt64Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt64Type.m
@@ -25,4 +25,11 @@ classdef UInt64Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/UInt8Type.m b/matlab/src/matlab/+arrow/+type/UInt8Type.m
index 898426e3a4..89715991ed 100644
--- a/matlab/src/matlab/+arrow/+type/UInt8Type.m
+++ b/matlab/src/matlab/+arrow/+type/UInt8Type.m
@@ -25,4 +25,11 @@ classdef UInt8Type < arrow.type.FixedWidthType
             obj@arrow.type.FixedWidthType(proxy);
         end
     end
+
+    methods (Access=protected)
+        function groups = getDisplayPropertyGroups(~)
+            targets = "ID";
+            groups = matlab.mixin.util.PropertyGroup(targets);
+        end
+    end
 end
\ No newline at end of file
diff --git a/matlab/test/arrow/type/tDate32Type.m b/matlab/test/arrow/type/tDate32Type.m
index 71a9e5cf48..c486772c45 100644
--- a/matlab/test/arrow/type/tDate32Type.m
+++ b/matlab/test/arrow/type/tDate32Type.m
@@ -40,28 +40,6 @@ classdef tDate32Type < hFixedWidthType
             testCase.verifyEqual(actualUnit, expectedUnit);
         end
 
-        function Display(testCase)
-            % Verify the display of Date32Type objects.
-            %
-            % Example:
-            %
-            %  Date32Type with properties:
-            %
-            %          ID: Date32
-            %    DateUnit: Day
-            %
-            type = testCase.ConstructionFcn(); %#ok<NASGU>
-            classnameLink = "<a href=""matlab:helpPopup arrow.type.Date32Type"" style=""font-weight:bold"">Date32Type</a>";
-            header = "  " + classnameLink + " with properties:" + newline;
-            body = strjust(pad(["ID:"; "DateUnit:"]));
-            body = body + " " + ["Date32"; "Day"];
-            body = "    " + body;
-            footer = string(newline);
-            expectedDisplay = char(strjoin([header body' footer], newline));
-            actualDisplay = evalc('disp(type)');
-            testCase.verifyEqual(actualDisplay, expectedDisplay);
-        end
-
         function DateUnitNoSetter(testCase)
             % Verify that an error is thrown when trying to set the value
             % of the DateUnit property.
diff --git a/matlab/test/arrow/type/tDate64Type.m b/matlab/test/arrow/type/tDate64Type.m
index 9345f6dbde..b9e9c3637e 100644
--- a/matlab/test/arrow/type/tDate64Type.m
+++ b/matlab/test/arrow/type/tDate64Type.m
@@ -40,28 +40,6 @@ classdef tDate64Type < hFixedWidthType
             testCase.verifyEqual(actualUnit, expectedUnit);
         end
 
-        function Display(testCase)
-            % Verify the display of Date64Type objects.
-            %
-            % Example:
-            %
-            %  Date32Type with properties:
-            %
-            %          ID: Date64
-            %    DateUnit: Millisecond
-            %
-            type = testCase.ConstructionFcn(); %#ok<NASGU>
-            classnameLink = "<a href=""matlab:helpPopup arrow.type.Date64Type"" style=""font-weight:bold"">Date64Type</a>";
-            header = "  " + classnameLink + " with properties:" + newline;
-            body = strjust(pad(["ID:"; "DateUnit:"]));
-            body = body + " " + ["Date64"; "Millisecond"];
-            body = "    " + body;
-            footer = string(newline);
-            expectedDisplay = char(strjoin([header body' footer], newline));
-            actualDisplay = evalc('disp(type)');
-            testCase.verifyEqual(actualDisplay, expectedDisplay);
-        end
-
         function DateUnitNoSetter(testCase)
             % Verify that an error is thrown when trying to set the value
             % of the DateUnit property.
diff --git a/matlab/test/arrow/type/tIsEqual.m b/matlab/test/arrow/type/tIsEqual.m
new file mode 100644
index 0000000000..babb08a04e
--- /dev/null
+++ b/matlab/test/arrow/type/tIsEqual.m
@@ -0,0 +1,52 @@
+%TISEQUAL Verifies the behavior of arrow.type.Type's isequal method on
+%nonscalar heterogeneous arrays.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements.  See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License.  You may obtain a copy of the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied.  See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef tIsEqual < matlab.unittest.TestCase
+
+    methods (Test)
+        % Test methods
+
+        function IsEqualTrue(testCase)
+            float32Type = arrow.float32();
+            timestampType = arrow.timestamp(TimeUnit="Second");
+            typeArray = [float32Type, timestampType];
+            testCase.verifyTrue(isequal(typeArray, typeArray));
+        end
+
+        function IsEqualFalse(testCase)
+            float32Type = arrow.float32();
+            timestampType1 = arrow.timestamp(TimeUnit="Second");
+            typeArray1 = [float32Type, timestampType1];
+
+            % Their dimensions are not equal
+            testCase.verifyFalse(isequal(typeArray1, typeArray1'));
+
+            % Corresponding elements are not equal
+            timestampType2 = arrow.timestamp(TimeUnit="Millisecond");
+            typeArray2 = [float32Type, timestampType2];
+            testCase.verifyFalse(isequal(typeArray1, typeArray2));
+
+            % Corresponding elements have different class types
+            stringType = arrow.string();
+            typeArray3 = [float32Type, stringType];
+            testCase.verifyFalse(isequal(typeArray1, typeArray3));
+        end
+
+    end
+
+end
\ No newline at end of file
diff --git a/matlab/test/arrow/type/tTime32Type.m b/matlab/test/arrow/type/tTime32Type.m
index 0bb467b1ba..86615312a1 100644
--- a/matlab/test/arrow/type/tTime32Type.m
+++ b/matlab/test/arrow/type/tTime32Type.m
@@ -82,28 +82,6 @@ classdef tTime32Type < hFixedWidthType
             testCase.verifyError(fcn, "MATLAB:validation:IncompatibleSize");
         end
 
-        function Display(testCase)
-            % Verify the display of Time32Type objects.
-            %
-            % Example:
-            %
-            %  Time32Type with properties:
-            %
-            %          ID: Time32
-            %    TimeUnit: Second
-            %
-            type = testCase.ConstructionFcn(TimeUnit="Second"); %#ok<NASGU>
-            classnameLink = "<a href=""matlab:helpPopup arrow.type.Time32Type"" style=""font-weight:bold"">Time32Type</a>";
-            header = "  " + classnameLink + " with properties:" + newline;
-            body = strjust(pad(["ID:"; "TimeUnit:"]));
-            body = body + " " + ["Time32"; "Second"];
-            body = "    " + body;
-            footer = string(newline);
-            expectedDisplay = char(strjoin([header body' footer], newline));
-            actualDisplay = evalc('disp(type)');
-            testCase.verifyEqual(actualDisplay, expectedDisplay);
-        end
-
         function TimeUnitNoSetter(testCase)
             % Verify that an error is thrown when trying to set the value
             % of the TimeUnit property.
diff --git a/matlab/test/arrow/type/tTime64Type.m b/matlab/test/arrow/type/tTime64Type.m
index 01460d9c1b..a698081990 100644
--- a/matlab/test/arrow/type/tTime64Type.m
+++ b/matlab/test/arrow/type/tTime64Type.m
@@ -83,28 +83,6 @@ classdef tTime64Type < hFixedWidthType
             testCase.verifyError(fcn, "MATLAB:validation:IncompatibleSize");
         end
 
-        function Display(testCase)
-            % Verify the display of Time64Type objects.
-            %
-            % Example:
-            %
-            %  Time64Type with properties:
-            %
-            %          ID: Time64
-            %    TimeUnit: Microsecond
-            %
-            type = testCase.ConstructionFcn(TimeUnit="Microsecond"); %#ok<NASGU>
-            classnameLink = "<a href=""matlab:helpPopup arrow.type.Time64Type"" style=""font-weight:bold"">Time64Type</a>";
-            header = "  " + classnameLink + " with properties:" + newline;
-            body = strjust(pad(["ID:"; "TimeUnit:"]));
-            body = body + " " + ["Time64"; "Microsecond"];
-            body = "    " + body;
-            footer = string(newline);
-            expectedDisplay = char(strjoin([header body' footer], newline));
-            actualDisplay = evalc('disp(type)');
-            testCase.verifyEqual(actualDisplay, expectedDisplay);
-        end
-
         function TimeUnitNoSetter(testCase)
             % Verify that an error is thrown when trying to set the value
             % of the TimeUnit property.
diff --git a/matlab/test/arrow/type/tTimestampType.m b/matlab/test/arrow/type/tTimestampType.m
index 6a626ebde7..1266faff4a 100644
--- a/matlab/test/arrow/type/tTimestampType.m
+++ b/matlab/test/arrow/type/tTimestampType.m
@@ -112,29 +112,6 @@ classdef tTimestampType < hFixedWidthType
             testCase.verifyError(fcn, "MATLAB:validation:IncompatibleSize");
         end
 
-        function Display(testCase)
-        % Verify the display of TimestampType objects.
-        %
-        % Example:
-        %
-        %  TimestampType with properties:
-        %
-        %          ID: Timestamp
-        %    TimeUnit: Second
-        %    TimeZone: "America/Anchorage"
-        %
-            type = arrow.timestamp(TimeUnit="Second", TimeZone="America/Anchorage"); %#ok<NASGU>
-            classnameLink = "<a href=""matlab:helpPopup arrow.type.TimestampType"" style=""font-weight:bold"">TimestampType</a>";
-            header = "  " + classnameLink + " with properties:" + newline;
-            body = strjust(pad(["ID:"; "TimeUnit:"; "TimeZone:"]));
-            body = body + " " + ["Timestamp"; "Second"; """America/Anchorage"""];
-            body = "    " + body;
-            footer = string(newline);
-            expectedDisplay = char(strjoin([header body' footer], newline));
-            actualDisplay = evalc('disp(type)');
-            testCase.verifyEqual(actualDisplay, expectedDisplay);
-        end
-
         function IsEqualTrue(testCase, TimeZone)
             % Verifies isequal method of arrow.type.TimestampType returns 
             % true if these conditions are met:
diff --git a/matlab/test/arrow/type/tTypeDisplay.m b/matlab/test/arrow/type/tTypeDisplay.m
new file mode 100644
index 0000000000..4d3c023da7
--- /dev/null
+++ b/matlab/test/arrow/type/tTypeDisplay.m
@@ -0,0 +1,256 @@
+%TTYPEDISPLAY Unit tests verifying the display of all classes within the
+%arrow.type.Type class hierarchy.
+
+% Licensed to the Apache Software Foundation (ASF) under one or more
+% contributor license agreements.  See the NOTICE file distributed with
+% this work for additional information regarding copyright ownership.
+% The ASF licenses this file to you under the Apache License, Version
+% 2.0 (the "License"); you may not use this file except in compliance
+% with the License.  You may obtain a copy of the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS,
+% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+% implied.  See the License for the specific language governing
+% permissions and limitations under the License.
+
+classdef tTypeDisplay < matlab.unittest.TestCase
+
+    properties(TestParameter)
+        TypeDisplaysOnlyID = {arrow.boolean(), ...
+                              arrow.uint8(), ...
+                              arrow.uint16(), ...
+                              arrow.uint32(), ...
+                              arrow.uint64(), ...
+                              arrow.int8(), ...
+                              arrow.int16(), ...
+                              arrow.int32(), ...
+                              arrow.int64(), ...
+                              arrow.float32(), ...
+                              arrow.float64(), ...
+                              arrow.float64(), ...
+                              arrow.string()}
+
+        TimeType = {arrow.time32(TimeUnit="Second"), ...
+                   arrow.time64(TimeUnit="Nanosecond")};
+
+        DateType = {arrow.date32(), ...
+                    arrow.date64()};
+    end
+
+    methods (Test)
+        function EmptyTypeDisplay(testCase)
+            % Verify the display of an empty arrow.type.Type instance.
+            %
+            % Example:
+            %
+            %  0x1 Type array with properties:
+            %
+            %    ID
+
+            type = arrow.type.Type.empty(0, 1);
+            typeLink = makeLinkString(FullClassName="arrow.type.Type", ClassName="Type", BoldFont=true);
+            dimensionString = makeDimensionString(size(type));
+            header = "  " + dimensionString + " " + typeLink + " array with properties:" + newline;
+            body = strjust(pad("ID"));
+            body = "    " + body;
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(type)');
+            testCase.verifyDisplay(actualDisplay, expectedDisplay);
+        end
+
+        function NonScalarArrayDifferentTypes(testCase)
+            % Verify the display of a nonscalar, heterogeneous arrow.type.Type array:
+            % 
+            % Example:
+            %
+            %  1×2 heterogeneous FixedWidthType (Float32Type, TimestampType) array with properties:
+            %
+            %    ID
+
+            float32Type = arrow.float32();
+            timestampType = arrow.timestamp();
+            typeArray = [float32Type timestampType];
+
+            heterogeneousLink =  makeLinkString(FullClassName="matlab.mixin.Heterogeneous", ClassName="heterogeneous",  BoldFont=false);
+            fixedWidthLink    =  makeLinkString(FullClassName="arrow.type.FixedWidthType",  ClassName="FixedWidthType", BoldFont=true);
+            timestampLink     = makeLinkString(FullClassName="arrow.type.TimestampType",   ClassName="TimestampType",   BoldFont=false);
+            float32Link       = makeLinkString(FullClassName="arrow.type.Float32Type",     ClassName="Float32Type",     BoldFont=false);
+
+            dimensionString = makeDimensionString(size(typeArray));
+            
+            header = "  " + dimensionString + " " + heterogeneousLink + " " + fixedWidthLink + ...
+                " (" +  float32Link + ", " + timestampLink + ") array with properties:" + newline;
+            body = "    " + "ID";
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(typeArray)');
+            testCase.verifyDisplay(actualDisplay, expectedDisplay);
+        end
+
+        function NonScalarArraySameTypes(testCase)
+            % Verify the display of a scalar, homogeneous arrow.type.Type array:
+            % 
+            % Example:
+            %
+            %  1×2 TimestampType array with properties:
+            %
+            %    ID
+            %    TimeUnit
+            %    TimeZone 
+
+            timestampType1 = arrow.timestamp(TimeZone="Pacific/Fiji");
+            timestampType2 = arrow.timestamp(TimeUnit="Second");
+            typeArray = [timestampType1 timestampType2];
+
+            timestampLink = makeLinkString(FullClassName="arrow.type.TimestampType", ClassName="TimestampType", BoldFont=true);
+            dimensionString = makeDimensionString(size(typeArray));
+            header = "  " + dimensionString + " " + timestampLink + " array with properties:" + newline;
+            body = strjust(["ID"; "TimeUnit"; "TimeZone"], "left");
+            body = "    " + body;
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(typeArray)');
+            testCase.verifyDisplay(actualDisplay, expectedDisplay);
+        end
+
+        function TestTypeDisplaysOnlyID(testCase, TypeDisplaysOnlyID)
+            % Verify the display of arrow.type.Type subclasses that only
+            % display the ID property.
+            %
+            % Example:
+            %
+            %  BooleanType with properties:
+            %
+            %          ID: Boolean
+
+            type = TypeDisplaysOnlyID;
+            fullClassName = string(class(type));
+            className = reverse(extractBefore(reverse(fullClassName), "."));
+            typeLink = makeLinkString(FullClassName=fullClassName, ClassName=className, BoldFont=true);
+            header = "  " + typeLink + " with properties:" + newline;
+            body = "    ID: " + string(type.ID);
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(type)');
+            testCase.verifyDisplay(actualDisplay, expectedDisplay);
+        end
+
+        function TestTimeType(testCase, TimeType)
+            % Verify the display of TimeType objects.
+            %
+            % Example:
+            %
+            %  Time32Type with properties:
+            %
+            %          ID: Time32
+            %    TimeUnit: Second
+
+            type = TimeType;
+            fullClassName = string(class(type));
+            className = reverse(extractBefore(reverse(fullClassName), "."));
+            typeLink = makeLinkString(FullClassName=fullClassName, ClassName=className, BoldFont=true);
+
+            header = "  " + typeLink + " with properties:" + newline;
+            body = strjust(pad(["ID:"; "TimeUnit:"]));
+            body = body + " " + [string(type.ID); string(type.TimeUnit)];
+            body = "    " + body;
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(type)');
+            testCase.verifyEqual(actualDisplay, expectedDisplay);
+        end
+
+        function TestDateType(testCase, DateType)
+            % Verify the display of DateType objects.
+            %
+            % Example:
+            %
+            %  Date32Type with properties:
+            %
+            %          ID: Date32
+            %    DateUnit: Day
+
+            type = DateType;
+            fullClassName = string(class(type));
+            className = reverse(extractBefore(reverse(fullClassName), "."));
+            typeLink = makeLinkString(FullClassName=fullClassName, ClassName=className, BoldFont=true);
+
+            header = "  " + typeLink + " with properties:" + newline;
+            body = strjust(pad(["ID:"; "DateUnit:"]));
+            body = body + " " + [string(type.ID); string(type.DateUnit)];
+            body = "    " + body;
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(type)');
+            testCase.verifyEqual(actualDisplay, expectedDisplay);
+        end
+
+        function Display(testCase)
+            % Verify the display of TimestampType objects.
+            %
+            % Example:
+            %
+            %  TimestampType with properties:
+            %
+            %          ID: Timestamp
+            %    TimeUnit: Second
+            %    TimeZone: "America/Anchorage"
+
+            type = arrow.timestamp(TimeUnit="Second", TimeZone="America/Anchorage"); %#ok<NASGU>
+            classnameLink = makeLinkString(FullClassName="arrow.type.TimestampType", ClassName="TimestampType", BoldFont=true);
+            header = "  " + classnameLink + " with properties:" + newline;
+            body = strjust(pad(["ID:"; "TimeUnit:"; "TimeZone:"]));
+            body = body + " " + ["Timestamp"; "Second"; """America/Anchorage"""];
+            body = "    " + body;
+            footer = string(newline);
+            expectedDisplay = char(strjoin([header body' footer], newline));
+            actualDisplay = evalc('disp(type)');
+            testCase.verifyEqual(actualDisplay, expectedDisplay);
+        end
+    end
+
+    methods
+        function verifyDisplay(testCase, actualDisplay, expectedDisplay)
+            % When the MATLAB GUI is running, '×' (char(215)) is used as
+            % the delimiter between dimension values. However, when the 
+            % GUI is not running, 'x' (char(120)) is used as the delimiter.
+            % To account for this discrepancy, check if actualDisplay 
+            % contains char(215). If not, replace all instances of
+            % char(215) in expectedDisplay with char(120).
+
+            tf = contains(actualDisplay, char(215));
+            if ~tf
+                idx = strfind(expectedDisplay, char(215));
+                expectedDisplay(idx) = char(120);
+            end
+            testCase.verifyEqual(actualDisplay, expectedDisplay);
+        end
+    end
+end
+
+function link = makeLinkString(opts)
+    arguments
+        opts.FullClassName(1, 1) string
+        opts.ClassName(1, 1) string
+        % When displaying heterogeneous arrays, only the name of the 
+        % closest shared anscestor class is displayed in bold. All other
+        % class names are not bolded.
+        opts.BoldFont(1, 1) logical
+    end
+
+    if opts.BoldFont
+        link = compose("<a href=""matlab:helpPopup %s"" style=""font-weight:bold"">%s</a>", ...
+            opts.FullClassName, opts.ClassName);
+    else
+        link = compose("<a href=""matlab:helpPopup %s"">%s</a>", opts.FullClassName, opts.ClassName);
+    end
+end
+
+function dimensionString = makeDimensionString(arraySize)
+    dimensionString = string(arraySize);
+    dimensionString = join(dimensionString, char(215));
+end
\ No newline at end of file